<Project-11 Calculator> 计算器 0.2 工时计算器 WorkHours Calculator HTTP + JS

灵感

给工人发工资是按小时计算的,每次都要上网,我比较喜欢用 Hours Calculator ,也喜欢它的其它的功能, 做个类似的。

我以为是 Python,结果在学 javascript 看 HTML,页面的基础还停留在 Frontpage 2000 因为 MS-Office 2000 里有的。

忽略我的美学... 已排版尽力

这是一个长期的项目当遇到生活计算时,就会添加进来,也许会吧
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/davenian/article/details/143054998   <- 开篇文章

工时计算器 Work Hours Calculator

这是一个工作时长计算器,用于根据用户输入的开始时间、结束时间以及休息时间来计算总工时。它支持12小时制和24小时制,并能够处理跨越午夜的情况。

目录结构

/11. Calculator
    /static
        - styles.css
        /workhours
            - workhourscal.js
        /time
            - timercal.js
    /templates
        - index.html
        /converters
            - time.html
            - workhours.html
    - app.py
 

服务端

同 https://blog.csdn.net/davenian/article/details/143054998 里面的内容

workhourscal.html

<!DOCTYPE html>
<!--workhours.html-->
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>工作小时数计算器</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div>
    <!-- 顶部导航按钮 -->
    <div class="nav-buttons">
        <!-- 返回上一页 -->
        <button onclick="history.back()">返回上一页</button>
        <!-- 返回主页 -->
        <a href="{{ url_for('index') }}">返回主页</a>
    </div>

    <!-- 内容区 -->
    <div class="content">
    <!-- 左侧的计算器容器 -->
        <div class="calculator-container  boxed-container">
            <div>
                <h2 class="rendered"> 工作时长计算器</h2>
            </div>
            <div>
                <div class="alignCenter note small" style="margin-bottom: 10px;">
                    输入不带冒号的时间:815, 1225 等          
                </div>
                <div class="clock-container">
                    <!-- 12 小时时钟 -->
                    <div class="clock clock"> 
                        <input name="clock" type="radio" id="clock_0" value="12" onchange="toggleAmPm();" checked="">
                        <label for="clock_0">12 hour clock</label>&nbsp;&nbsp;&nbsp;
                    </div>
                    <!-- 24 小时时钟 -->
                    <div class="cell clock">
                        <input name="clock" type="radio" id="clock_1" value="24" onchange="toggleAmPm();">
                        <label for="clock_1">24 hour clock</label>        
                    </div>
                </div>
                <!-- AM/PM 选择框 -->
                <div class="clock-container">
                    <div class="cell">
                        <label for="startTime">开始时间:</label>
                        <input type="text" id="startTime" placeholder="hhmm" required maxlength="4" pattern="^([12]?[0-9][0-6][0-9])?$" inputmode="numeric" title="请输入有效的时间格式!">
                         <!-- AM/PM 选择框 -->
                        <div id="startAmPmContainer">
                            <select id="startAmPm">
                                <option value="AM" selected>AM</option>
                                <option value="PM">PM</option>
                        </select>
                        </div> 
                    </div>
                </div>
                <div class="clock-container">
                    <div class="cell">   
                        <label for="endTime">结束时间:</label>
                        <input type="text" id="endTime" placeholder="hhmm" required maxlength="4" pattern="^([12]?[0-9][0-6][0-9])?$" inputmode="numeric" title="请输入有效的时间格式!">
                        <!-- AM/PM 选择框 -->
                        <div id="endAmPmContainer">
                            <select id="endAmPm">
                                <option value="AM">AM</option>
                                <option value="PM" selected>PM</option>
                            </select>
                        </div> 
                    </div>
                </div>
                <div class="clock-container">
                    <div class="row">
                        <div class="cell alignLeft">
                            <label for="break_minutes">休息时间:</label>
                            <input type="text" id="break_minutes"  placeholder="0" inputmode="numeric" value="0" size="4" maxlength="3" onfocus="this.select()"> 分钟
                        </div>
                    </div>
                </div>
            </div>
            <div class="button-group">
                <div class="floatLeft">   
                    <button class="clear-btn" onclick="clearFields()">清除</button>
                </div>
                
                <div class="floatRight">
                    <button id="calculateHours" class="calculator-btn">工时计算</button>
                
                </div>
            </div>
            <div>
                <p></p>
                <div class="celleft">
                    <h3 style="display: inline;">结果: </h3>
                    <span id="answer"></span>
                </div>
                
                <!-- 使用标准的表格结构替换 div 模拟的表格 -->
                <table class="prettytable centered">
                    <tr>
                        <th>时间合计(hh:mm)</th>
                        <td id="totalTime">00:00</td>
                    </tr>
                    <tr>
                        <th>十进制显示</th>
                        <td id="decimalHours">0.00 hours</td>
                    </tr>
                    <tr>
                        <th>分钟统计</th>
                        <td id="totalMinutes">0 minutes</td>
                    </tr>
                </table>
            </div>
        </div>
    <!-- 右侧的说明文字 -->
        <div class="description">
        <h3>使用这个计算器来累加时间表或工时卡的工时。</h3>
        <p>只输入整数,如 1215 代表 12:15,或 137 代表 1:37。对于完整的工时卡,请使用工时卡计算器。</p>
        <p>输入开始时间和结束时间时,不要使用 "." 或 ":"。</p>
        <p>如果输入的数字为 1 到 12 之间的单个整数,系统将假定时间为 1:00 到 12:00。</p>
        <p>系统假定“12 pm”为中午,“12 am”为午夜。</p>
        <h3>将数字时间转换为十进制小时</h3>
        <p>假设您计算的总时间为 7:15(7 小时 15 分钟),其等效的十进制时间为 7.25 小时。您需要使用十进制小时来计算工资。</p>
        <h3>将分钟转换为十进制小时</h3>
        <p>7:15 表示 7.0 小时外加 15 分钟。您需要将分钟部分转换为小时。</p>
        <p>15 分钟乘以 1 小时除以 60 分钟,以小时为单位:</p>
        <p>15 分 × (1 小时 / 60 分钟) = (15/60) 小时 = 0.25 小时</p>
        <p>将 0.25 加到 7.0,我们的总时间就是 7.0 + 0.25 = 7.25 小时。</p>
        <h3>反向操作:将十进制小时转换为分钟</h3>
        <p>0.25 小时乘以每小时 60 分钟:</p>
        <p>0.25 小时 × (60 分钟 / 1 小时) = (0.25 × 60) 分钟 = 15 分钟。</p>
        </div>
    <script src="{{ url_for('static', filename='workhours/workhourscal.js') }}"></script>
    </div>
</body>
</html>

说明:

CSS 分开, <div></div> 写代码时,一定要格式对齐,至少这个必须的。display:flexed 慎用 尤其是行间距缩进时。

workhourscal.js

// workhourscal.js
document.addEventListener('DOMContentLoaded', function() { //必须在 function 之前
    // 绑定计算按钮的事件监听器
    document.getElementById('calculateHours').addEventListener('click', calculateHours);
    
    // 绑定清除按钮的事件监听器
    // document.getElementById('clearFields').addEventListener('click', clearFields);
});

function toggleAmPm() {
    // 获取选择的时钟模式
    var is24HourClock = document.getElementById('clock_1').checked;
    
    // 获取 AM/PM 选择框容器
    var startAmPmContainer = document.getElementById('startAmPmContainer');
    var endAmPmContainer = document.getElementById('endAmPmContainer');
    
    // 如果选择了24小时制,隐藏AM/PM选择框;否则显示
    if (is24HourClock) {
        startAmPmContainer.style.display = 'none';
        endAmPmContainer.style.display = 'none';
    } else {
        startAmPmContainer.style.display = 'block';
        endAmPmContainer.style.display = 'block';
    }
}

function calculateHours() {
    const startTime = document.getElementById('startTime').value;
    const endTime = document.getElementById('endTime').value;
    const is24HourClock = document.getElementById('clock_1').checked; // 检查是否是24小时制
    let startAmPm = '';
    let endAmPm = '';

    if (!is24HourClock) {
        startAmPm = document.getElementById('startAmPm').value;
        endAmPm = document.getElementById('endAmPm').value;
    }

    const breakMinutes = parseInt(document.getElementById('break_minutes').value) || 0;

    // 重置提示和变量
    document.getElementById('answer').textContent = '';  // 清空之前的提示
    let midnightCrossed = false;  // 初始化标记变量
    let answerText = '';  // 初始化提示内容

    // 验证输入的时间格式是否正确
    if (!isValidTime(startTime) || !isValidTime(endTime)) {
        document.getElementById('answer').textContent = '请输入有效的时间格式 (hhmm)';
        return;
    }

    // 将时间转换为分钟(如果是24小时制,则忽略AM/PM)
    const startMinutes = timeToMinutes(startTime, startAmPm, is24HourClock);
    const endMinutes = timeToMinutes(endTime, endAmPm, is24HourClock);

    let totalMinutes = endMinutes - startMinutes - breakMinutes;
    
    // 处理跨越午夜的情况:如果结束时间早于开始时间,自动处理为跨越午夜的情况
    if (totalMinutes < 0) {
        totalMinutes += 1440; // 加上一天的分钟数
        answerText = ' 注意:时间跨越了午夜!'; // 设置提醒文本
        midnightCrossed = true; // 标记为跨越了午夜
    }

    // 计算小时和分钟
    const hours = Math.floor(totalMinutes / 60);
    const minutes = totalMinutes % 60;

    // 计算十进制小时
    const decimalHours = (totalMinutes / 60).toFixed(2);

    // 输出调试
    console.log(`Hours: ${hours}, Minutes: ${minutes}, Decimal: ${decimalHours}, Total Minutes: ${totalMinutes}`);

    // 将结果更新到表格的相应单元格中
    document.getElementById('totalTime').textContent = `${hours}:${minutes.toString().padStart(2, '0')}`;  // 总时间 (hh:mm)
    document.getElementById('decimalHours').textContent = `${decimalHours} hours`;  // 十进制小时
    document.getElementById('totalMinutes').textContent = `${totalMinutes} minutes`;  // 总分钟数

    // 如果跨越了午夜,显示提示信息
    if (midnightCrossed) {
        document.getElementById('answer').textContent = answerText;  // 显示跨越午夜的提醒
    }
}

function timeToMinutes(time, amPm, is24HourClock) {
    let hours = parseInt(time.slice(0, time.length - 2), 10);
    let minutes = parseInt(time.slice(-2), 10);

    // 如果是24小时制,忽略 AM/PM 处理
    if (!is24HourClock) {
        if (amPm === 'PM' && hours !== 12) {
            hours += 12;
        } else if (amPm === 'AM' && hours === 12) {
            hours = 0;
        }
    }

    return hours * 60 + minutes;
}

function isValidTime(time) {
    return /^([01]?[0-9]|2[0-3])[0-5][0-9]$/.test(time);  // 验证24小时制时间格式
}


function clearFields() {
    document.getElementById('startTime').value = '';
    document.getElementById('endTime').value = '';
    document.getElementById('break_minutes').value = '0';
    document.getElementById('answer').textContent = '';
    document.getElementById('totalTime').textContent = `00:00`;
    document.getElementById('decimalHours').textContent = `0.00 hours`;
    document.getElementById('totalMinutes').textContent = `0 minutes`;
    document.getElementById('answerText').textContent = ``;
    //document.getElementById('midnightCrossed').textContent = ``;
}

说明:

一定要放在第一行!!!

document.addEventListener('DOMContentLoaded', function() { //必须在 function 之前
    // 绑定计算按钮的事件监听器
    document.getElementById('calculateHours').addEventListener('click', calculateHours);
    
    // 绑定清除按钮的事件监听器
    // document.getElementById('clearFields').addEventListener('click', clearFields);
});

当网页的 DOM 加载完成时,这段代码会运行。它会给 id="calculateHours()" 的按钮绑定一个点击事件,当按钮被点击时会触发 calculateHours() 函数,进行工时计算。

function toggleAmPm()

用来切换12小时和24小时制。当用户选择24小时制时,它会隐藏 AM/PM 选择框。

计算工时的主函数 function calculateHours():

负责计算开始时间和结束时间之间的总工时。它根据输入的时间,判断是否是24小时制,计算时间差(总工时),并且在跨越午夜时进行处理,提示用户输入的时间"跨越了午夜"。

时间转换函数 function timeToMinutes()

将输入的时间(格式为 hhmm)转换为总分钟数。如果是12小时制,还会根据 AM/PM 来调整小时数。例如, 2:00 会被转换为 14:00(即 840 分钟)

时间格式验证函数 function isValidTime()

用于输入的时间格式是否正确(格式应该是 hhmm )。例如,909 是合法的时间,而 9090 则不是。

清除输入字段函数 function clearFields()

  • 这个函数会清空所有输入字段和结果显示区域,恢复页面到初始状态。

        代码流程总结:

  •     输入时间:输入开始时间、结束时间以及休息时间。
  •     选择12/24小时制:根据选择,显示或隐藏 AM/PM 选择框。
  •     计算工时:点击 "计算" 按钮后,程序根据输入的时间计算工时,并处理跨越午夜的情况。
  •     显示结果:计算完成后,工时结果会显示在页面的对应位置。如果输入的时间跨越了午夜,会有相应提示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/895836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Cloudlog delete_oqrs_line 未授权SQL注入漏洞复现

0x01 产品简介 Cloudlog 是一个自托管的 PHP 应用程序,可让您在任何地方记录您的业余无线电联系人。使用PHP和MySQL构建的基于Web的业余无线电记录应用程序支持从HF到微波的一般站记录任务 0x02 漏洞概述 Cloudlog delete_oqrs_line 接口存在未授权SQL注入漏洞,未经身份验…

Marin说PCB之GMSL2 的Layout走线的注意事项

昨天有一位铁粉私信问我能不能讲解一下GMSL走线的一些注意事项啥的&#xff0c;我说当等我从以色列出差回来就给你更新一下这个&#xff0c;当然后来又很多的热心的粉丝提出很多的想法&#xff0c;我会一一给大家解答分享的&#xff0c;本期文章主要先给大家分享一下美信的手册…

[Python学习日记-50] Python 中的序列化模块 —— pickle 和 json

[Python学习日记-50] Python 中的序列化模块 —— pickle 和 json 简介 pickle 模块 json 模块 pickle VS json 简介 什么叫序列化&#xff1f; 序列化指的是将对象转换为可以在网络上传输或者存储到文件系统中的字节流的过程。序列化使得对象可以被保存、传输和恢复&#…

机器学习与神经网络:科技的星辰大海

前提 近日&#xff0c;2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者&#xff0c;这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家&#xff0c;如今却将全球范围内对机器学习和神经网络的研究和开发作为了一…

基于K8S的StatefulSet部署mysql主从

StatefulSet特性 StatefulSet的网络状态 拓扑状态&#xff1a;应用的多个实例必须按照某种顺序启动&#xff0c;并且必须成组存在&#xff0c;例如一个应用中必须存在一 个A Pod和两个B Pod&#xff0c;且A Pod必须先于B Pod启动的场景 存储状态&#xff1a;应用存在多个实例…

ChatGPT01-preivew体验报告:内置思维链和多个llm组合出的COT有啥区别呢?丹田与练气+中学生物理奥赛题测试,名不虚传还是名副其实?

一个月前&#xff0c;o1发布的时候&#xff0c;我写了篇文章介绍 逻辑推理能力堪比博士生&#xff0c;OpenAI发布全新AI模型系列&#xff1a; o1 - 大模型或许进入新阶段&#xff0c;还翻译了官方的介绍 解密OpenAI o1是如何让LLMs获得逻辑推理能力的 - CoT * RL&#xff0c;也…

【Linux】多线程安全之道:互斥、加锁技术与底层原理

目录 1.线程的互斥 1.1.进程线程间的互斥相关背景概念 1.2.互斥量mutex的基本概念 所以多线程之间为什么要有互斥&#xff1f; 为什么抢票会抢到负数&#xff0c;无法获得正确结果&#xff1f; 为什么--操作不是原子性的呢&#xff1f; 解决方式&#xff1a; 2.三种加锁…

基于SpringBoot+Vue的厨艺交流系统的设计与实现(源码+定制开发)厨艺知识与美食交流系统开发、在线厨艺分享与交流平台开发、智能厨艺交流与分享系统开发

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

第五届人工智能与教育国际学术会议(ICAIE 2024)

文章目录 一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询 一、会议详情 二、重要信息 大会官网&#xff1a;https://ais.cn/u/vEbMBz提交检索&#xff1a;EI Compendex、IEEE Xplore、Scopus 三、大会介绍 第五届人工智能与教育国际学术会议&#x…

java逻辑运算符 C语言结构体定义

1. public static void main(String[] args) {System.out.println(true&true);//&两者均为true才trueSystem.out.println(false|false);// | 两边都是false才是falseSystem.out.println(true^false);//^ 相同为false&#xff0c;不同为trueSystem.out.println(!false)…

【python爬虫实战】爬取全年天气数据并做数据可视化分析!附源码

由于篇幅限制&#xff0c;无法展示完整代码&#xff0c;需要的朋友可在下方获取&#xff01;100%免费。 一、主题式网络爬虫设计方案 1. 主题式网络爬虫名称&#xff1a;天气预报爬取数据与可视化数据 2. 主题式网络爬虫爬取的内容与数据特征分析&#xff1a; - 爬取内容&am…

蜜罐技术的出现究竟影响了什么

自网络诞生以来&#xff0c;攻击威胁事件层出不穷&#xff0c;网络攻防对抗已成为信息时代背景下的无硝烟战争。然而&#xff0c;传统的网络防御技术如防火墙、入侵检测技术等都是一种敌暗我明的被动防御&#xff0c;难以有效应对攻击者随时随地发起的无处不在的攻击和威胁。蜜…

IO多路复用概述与epoll简介

一、引言 在网络编程中&#xff0c;高并发的场景下处理大量连接请求是一项挑战。传统的阻塞式IO模型会让线程在等待数据的过程中陷入停顿&#xff0c;导致系统效率低下。为了解决这个问题&#xff0c;IO多路复用应运而生。它允许一个线程同时监听多个文件描述符&#xff08;如…

Gin框架操作指南02:JSON渲染

官方文档地址&#xff08;中文&#xff09;&#xff1a;https://gin-gonic.com/zh-cn/docs/ 注&#xff1a;本教程采用工作区机制&#xff0c;所以一个项目下载了Gin框架&#xff0c;其余项目就无需重复下载&#xff0c;想了解的读者可阅读第一节&#xff1a;Gin操作指南&#…

qt creator 开发环境的安装

1.找官网 官网地址&#xff1a;Installation | Qt Creator Documentation 点 Parent Directory 继续点 Parent Directory 点 archive/ 2.下载在线安装器 点 online_ainstallers 选择在线安装器版本 选择对应版本后进入下载列表&#xff0c;根据自己的系统选择下载。 下载后…

DreamFace 4.7.1 | 图片说话,数字人

DreamFace是一款可以把静态图片变成动态视频的软件&#xff0c;操作简单&#xff0c;内置多种模板可供选择。此外&#xff0c;还支持将图片变得更清晰或者转换成卡通风格等功能&#xff0c;非常适合喜欢创意视频制作的用户。通过安装软件后&#xff0c;根据提示选择需要转换的静…

c++ pdf文件提取txt文本示例

最近抽空采用之前封装的接口将pdf文件提取出txt文本&#xff0c;顺利完成&#xff0c;界面如下所示&#xff1a; 提起的效果如下所示&#xff1a; 输出的txt文本内容如下&#xff1a; 下载链接&#xff1a;https://download.csdn.net/download/u011269801/89905548

vue中如何检测数组变化(vue基础,面试,源码级讲解)

大家有什么不明白的地方可以分享在评论区&#xff0c;大家一起探讨哦~~ &#xff08;如果对数据劫持还有所不明白的小伙伴&#xff0c;可以去看看上一篇文章哦&#xff09; 在vue2中&#xff0c;是如何对数组进行劫持的呢&#xff1f; 简单代码实现&#xff1a; 在vue2中&…

pytorh学习笔记——cifar10(三)模仿VGGNet创建卷积网络

VGG16是由牛津大学视觉几何组&#xff08;Visual Geometry Group&#xff09;提出的一种深度卷积神经网络模型。 VGGNet 探索了卷积神经网络的深度与其性能之间的关系&#xff0c;成功地构筑了 16~19 层深的卷积神经网络&#xff0c;同时拓展性又很强&#xff0c;迁移到其它图片…

反转链表 K个一组翻转链表

目录 LeetCode206 反转链表 LeetCode92 反转链表II LeetCode25 K个一组翻转链表 LeetCode206 反转链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x)…