Java 统计连续签到天数

2023-11-02

说明
签到功能根据业务情况的不同大致分为两种,一种是只要进入系统就会默认签到,另外一种是进入系统之后需要用户手动点击签到按钮进行签到。两种情况最大的区别就是,自动签到连续签到天数肯定至少为1天。而手动签到的情况则需要考虑断签的情况。

1、自动签到下统计连续签到天数

    public static void main(String[] args) {
        try {
            /**
             * 造一些测试数据,这里就不去数据库里查了,一般正常是数据库有个表记录签到记录
             */
            List<String> signInDateStrs = new ArrayList<>();
            signInDateStrs.add("2019-12-31");
            signInDateStrs.add("2020-01-01");
            signInDateStrs.add("2020-01-02");
            List<Date> signInDates = new ArrayList<>();
            for (String dateStr : signInDateStrs) {
                Calendar calendarTo = Calendar.getInstance();
                calendarTo.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateStr));
                Calendar c = Calendar.getInstance();
                c.setTimeInMillis(0);
                c.set(calendarTo.get(Calendar.YEAR), calendarTo.get(Calendar.MONTH),
                        calendarTo.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
                signInDates.add(c.getTime());
            }

            int count = persistentDay(signInDates);
            System.out.println("连续签到了" + count + "天");
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 自动签到的情况,只要一进入系统就会签到,所以连续签到肯定至少为1天
     * @param signInDates
     * @return
     */
    private static int persistentDay(List<Date> signInDates){
        //定义一个变量表示连续签到天数,从1开始
        int continuousDays = 1;

        //1. 注意先对时间进行从小到大排序(可以在数据库里查的时候就根据时间排序,也可以查询出来之后再排序)

        /**
         * 2. 从最大的时间开始往前比较,因为我们是要拿连续签到的时间,这样才有意义,减少无谓的比较
         */
        Calendar later = Calendar.getInstance();
        Calendar before = Calendar.getInstance();
        for (int i = signInDates.size() - 1; i > 0; i--){
            later.setTime(signInDates.get(i));
            before.setTime(signInDates.get(i - 1));
            //前一天 + 1天 = 后一天,则视为连续签到
            before.add(Calendar.DAY_OF_MONTH,1);
            if (later.get(Calendar.YEAR) == before.get(Calendar.YEAR)
                    && later.get(Calendar.MONTH) == before.get(Calendar.MONTH)
                    && later.get(Calendar.DAY_OF_YEAR) == before.get(Calendar.DAY_OF_YEAR)){
                continuousDays++;
            }else {
                //只要遇到不连续的就不用再往前比较了
                break;
            }
        }
        return continuousDays;
    }

2、手动签到下统计连续签到天数

    public static void main(String[] args) {
        /**
         * 造一些测试数据,为了简单演示就不去数据库查寻签到记录了
         * 注意时间要从小到大排序,如果从数据库里查询的时候,可以根据这个时间进行order by
         * 也可以查询出来再程序排序
         */
        List<String> signInDateStrs = new ArrayList<>();
        signInDateStrs.add("2019-12-31");
        signInDateStrs.add("2020-03-02");
        signInDateStrs.add("2020-03-03");
        List<Date> signInDates = new ArrayList<>();
        try {
            for (String dateStr : signInDateStrs) {
                Calendar calendarTo = Calendar.getInstance();
                calendarTo.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateStr));
                Calendar c = Calendar.getInstance();
                c.setTimeInMillis(0);
                c.set(calendarTo.get(Calendar.YEAR), calendarTo.get(Calendar.MONTH),
                        calendarTo.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
                signInDates.add(c.getTime());
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }


        int count = persistentDay(signInDates);
        System.out.println("已连续签到 " + count + "天");
    }

    /**
     * 需要手动点击签到的情况
     * @param signInDates
     * @return
     */
    private static int persistentDay(List<Date> signInDates) {
        //定义一个变量表示连续签到天数,从1开始
        int continuousDays = 1;

        /**
         * 如果手动签到的话需要考虑
         * 把排序之后的签到记录时间中最大的那个时间拿出来与 昨天 进行比较,如果相等证明还是连续签到的,如果不等则连续签到变成0
         */
        Calendar yesterday = Calendar.getInstance();
        yesterday.setTime(new Date());
        yesterday.add(Calendar.DAY_OF_MONTH, -1);

        Calendar lastDay = Calendar.getInstance();
        lastDay.setTime(signInDates.get(signInDates.size() - 1));
        if (yesterday.get(Calendar.YEAR) != lastDay.get(Calendar.YEAR)
                || yesterday.get(Calendar.MONTH) != lastDay.get(Calendar.MONTH)
                || yesterday.get(Calendar.DAY_OF_YEAR) != lastDay.get(Calendar.DAY_OF_YEAR)) {
            //昨天没有签到
            continuousDays = 0;
            return continuousDays;
        }

        /**
         * 2. 从最大的时间开始往前比较,因为我们是要拿连续签到的时间,这样才有意义,减少无谓的比较
         */
        Calendar later = Calendar.getInstance();
        Calendar before = Calendar.getInstance();
        for (int i = signInDates.size() - 1; i > 0; i--) {
            later.setTime(signInDates.get(i));
            before.setTime(signInDates.get(i - 1));
            //前一天 + 1天 = 后一天,则视为连续签到
            before.add(Calendar.DAY_OF_MONTH, 1);
            if (later.get(Calendar.YEAR) == before.get(Calendar.YEAR)
                    && later.get(Calendar.MONTH) == before.get(Calendar.MONTH)
                    && later.get(Calendar.DAY_OF_YEAR) == before.get(Calendar.DAY_OF_YEAR)) {
                continuousDays++;
            } else {
                //只要遇到不连续的就不用再往前比较了
                break;
            }
        }
        return continuousDays;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 统计连续签到天数 的相关文章

  • 从txt文件中读取数据而不下载它?

    我想从提供的文本文件中解析信息 有没有一种方法可以在应用程序中执行此操作 而无需先下载文件 以某种方式传输文本内容 打开到 URL 的 Http 连接 使用内置 HttpURLConnection 或使用 commons httpclien
  • java 拖放

    我尝试熟悉java中的拖放 但我发现的所有教程都是 让我生气 我想要的只是从 JList 包含在名为 UserPanel 的自制 JPanel 中 拖动 PublicUserLabel 并将其放入从 JTabbedPanel 继承的自制类中
  • Selector.close() 是否关闭所有客户端套接字?

    我是 nio 套接字的新手 我已经使用 nio 套接字编写了一个服务器 现在我正在尝试编写关闭钩子以确保通过清理资源正常退出 我的问题是Selector close 方法关闭所有客户端套接字 如果没有 请告诉我如何访问所有客户端套接字 而无
  • 如何重复一段文本中的每个字母?爪哇语

    就像在口吃中一样 如果文本为 dean 并且乘数为 3 则结果将是 dddeeeaaannn 由提供的乘数指定的次数 public static void repeatLetters String text dean int n 3 Str
  • JAX-WS 入门 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有人可以推荐一些关于 JAX WS 入门的好教程吗 使用各种工具 如 wsgen 等 您可以从这里开始 通过 Java SE 6 平台介绍
  • 无法在 Intellij 中运行主类[重复]

    这个问题在这里已经有答案了 我有以下项目结构 ProjectRoot src Main examples libs My src文件夹被标记为sources在 Intellij 中 现在 当我想运行 Main 类时 出现以下错误 Excep
  • Jenkins 未显示 Maven 编译器错误

    在 Jenkins 中构建多模块 maven 3 项目时 如果出现构建错误 我们会收到一条神秘消息 表明 Maven 编译器插件失败 这在上周才刚刚开始发生 INFO BUILD FAILURE INFO INFO Total time 1
  • Java:一种将 Mime(内容)类型与 CommonsMultipartFile 中的文件扩展名相匹配的方法

    在我的公司 出于额外原因 我需要将 mime 类型与文件扩展名进行比较 我有一个CommonsMultipartFile 我正在尝试找出进行这种比较的最佳方法 我见过一个MimetypesFileTypeMap 但不确定这是否适用于此 我试
  • 传递自定义类型查询参数

    如何接受自定义类型查询参数 public String detail QueryParam request final MYRequest request 上面的行在启动服务器时出现错误 jersey server model ModelV
  • 当我们使用赋值而不是比较时,如何评估 if/while 条件?

    我在学习 Java 的 OCA OCP 时发现了这个令人惊讶的事情 下面是第一段代码 其中 if 测试条件 部分 让我惊讶 public class BooleanIf public static void main String args
  • 如何使用 aether 从 Java 找到最新版本的 Maven 工件?

    他们的文档非常薄弱 我无法弄清楚 我找到了部分答案here https stackoverflow com questions 27428068 how to retrieve the latest also snapshot versio
  • java:为什么主线程等待子线程完成

    我有一个简单的java程序 主线程 main 创建并启动另一个线程t class T extends Thread Override public void run while true System out println Inside
  • 我的 Kafka 流应用程序刚刚退出,代码为 0,什么也不做

    为了尝试 Kafka 流 我这样做了 public static void main String args final StreamsBuilder builder new StreamsBuilder final Properties
  • 扩展多个类

    我知道 Java 不支持多重继承 因为不允许扩展多个类 我只是想知道我的问题是否有解决方法 我有一个名为CustomAction需要扩展两个抽象类 BaseAction and QuoteBaseAction 我无法更改这些抽象类中的任何一
  • javadoc 子集/java 库组织

    我自己从来没有运行过javadoc 无论是在命令行还是ant 的 javadoc 任务 http ant apache org manual Tasks javadoc html 我将使用 ant 我需要为我编写的库生成 javadoc 问
  • 在 Eclipse RCP 应用程序中禁用插件贡献

    我经常遇到这个问题 但尚未找到解决方案 每当我编写一个新的基于 Eclipse RCP 的应用程序并包含来自 Eclipse 平台的插件时 我都会 继承 其中一些插件的 UI 贡献 大多数贡献 菜单项 键盘快捷键 属性页 都很有用 但有时我
  • 添加 char 和 int

    据我了解 字符是一个字符 即一个字母 一个digit 标点符号 制表符 空格或类似的东西 因此 当我这样做时 char c 1 System out println c 输出 1 正是我所期望的 那么为什么当我这样做时 int a 1 ch
  • 如果 Modelmapper 中的整个属性为空,如何排除它们

    ModelMapper 是否 http modelmapper org http modelmapper org 支持什么排除属性 如果该值为空 我刚刚找到了 PropertyMap 但这对我来说是一种限制 因为我必须描述我想要的特定属性
  • 假布尔值=真?

    我在一本书中找到了这段代码 并在 Netbeans 中执行了它 boolean b false if b true System out println true else System out println false 我只是不明白为什
  • Graphics2D setfont() 严重减慢了 java 应用程序的启动速度

    我正在用java制作一个游戏 它每秒刷新60次 每次执行循环时 我都会使用 g2d 来绘制图像和字符串 如果我这样做的话一切都会很好g2d setFont new Font Arial Font PLAIN 8 和抽绳 这将是正常的 但如果

随机推荐

  • 角谷猜想(Collatz conjecture)--用 python 语言实现

    老师布置的一个小作业 用python代码实现角谷猜想 下面就给大家提供一个思路 供大家参考 角谷猜想 n 是一个自然数 如果 n 是奇数 则 n 3 n 1 如果 n 是偶数 则 n n 2 当 n 1 时输出整个计算过程的序列 如当 n
  • linux 内核 发送数据,linux 内核tcp数据发送的实现

    在分析之前先来看下SO RCVTIMEO和SO SNDTIMEO套接口吧 前面分析代码时没太注意这两个 这里算是个补充 SO RCVTIMEO和SO SNDTIMEO套接口选项可以给套接口的读和写 来设置超时时间 在unix网络编程中 说是
  • Docker: 容器如何访问windows宿主机中的服务,在容器中访问宿主机部署的服务,在容器中ping到宿主机

    一 使用背景 1 项目中使用到srs作为流媒体服务器 2 测试阶段时 将srs部署在windows10中 3 需要对推流拉流做认证操作 二 查看windows的hosts文件 C Windows System32 drivers etc h
  • 338. Counting Bits

    class Solution public vector
  • 接口和抽象类的异同点

    相同点 1 抽象类和接口都不能直接实例化 创建对象 2 抽象类的子类 或接口的实现类 都必须实现抽象类 或接口 中全部的抽象方法 才可以被实例化 否则 该类仍然为抽象类 不同点 1 关键字不同 抽象类子类使用extends关键字来继承抽象类
  • Qt的KeyEvent捕获Ctrl+C等快捷键/热键

    1 必须设置widget可以拥有焦点 注意 默认的focusPolicy是NoFocus 这会导致无法捕获Ctrl Alt Shfit 之外的字符按键 setFocusPolicy Qt StrongFocus 窗口将通过鼠标点击 按tab
  • 迪杰特斯拉算法-最短路径问题(浙大计算机机试题)

    今天写了一道可以用迪杰特斯拉算法实现的题目 题目如下 给你n个点 m条无向边 每条边都有长度d和花费p 给你起点s终点t 要求输出起点到终点的最短距离及其花费 如果最短距离有多条路线 则输出花费最少的 写的代码如下 但是一直不通过 incl
  • (二)用多线程管理TCP多个客户端连接服务器

    该程序的服务端大概工作逻辑如左图 首先说说这个程序的作用 这个程序可用于多个客户端通过连接服务器来互相通信 如qq群聊 当一个客户端有信息发过来后 服务端就会通过客户端队列转发给其他客户端 先上代码 TCP服务端 include myhea
  • GIT学习资料

    Git详解之一 Git起步 Git详解之二 Git基础 Git详解之三 Git分支 Git详解之四 服务器上的Git Git详解之五 分布式Git Git详解之六 Git工具 Git详解之七 自定义Git Git详解之八 Git与其他系统
  • C++并发编程框架Theron(5)——File reader(1)

    1 前言 在上一篇博文 我主要通过Hello world 的示例 介绍了actors frameworks messages和receivers几个构建Theron框架程序的要点 但是Hello world 实例只是一个再简单不过的单act
  • 关于android studio 出现Error:Execution failed for task ':app:preDebugAndroidTestBuild'. 的解决办法

    前段时间打开Android studio 在build过程中总会出现以下错误 Error Execution failed for task app preDebugAndroidTestBuild gt Conflict with dep
  • Windows认证原理解析基础入门

    0x01 前言简介 0x02 基本介绍 1 本地登录认证 2 网络登录认证 0x03 LM NTLM 版本优缺 0x04 LM NTLM 生成原理 1 LM Hashes 生成实例 2 NTLM Hashes 生成实例 0x05 LM NT
  • 文件读取-python与java对比

    最近开始接触python 发现python的语法真的是简单 下面是读取文件的实例对比 Java package com ztesoft oss iominterface httpServlet toIOM import java io Bu
  • 高仿钉钉和小米的日历控件,很实用

    http mp weixin qq com s cWD7ex7WVT8bzQpxFHmCyA ref myread
  • mysql sum 重复计算_mysql join sum时数据重复问题及解决方案

    当我们使用mysql的join功能从多张表中取出数据并使用sum分别对取出的数据求和时 会发现sum出来的值是不对的 往往是正确值的整数倍 为什么会出现这样的情况呢 复现 假设有两张表 user buy 和user sell 分别记录了用户
  • 基于Qt的智能车载系统嵌入式项目(正点原子IMX6ULL开发板)

    基于正点原子的IMX6ULL开发板的智能车载系统 Qt 提示 该项目借鉴了不少大佬的代码 我没有自己造轮子 代码在文章末尾 同时附上参考链接 本人其他项目链接基于linux的智能仓储项目 基于Qt的人脸识别 基于STM32的智能家居 移植人
  • Kali 2 Kali 2018更新源

    这个源指的是软件源 也就是说你用apt get install xxx安装软件时 系统下载软件的地方 一般默认为国外的链接 所以速度比较慢 需要换成国内的源 设置kali的更新源 在终端中打开sources list root kali v
  • 海康威视web插件【浏览器部分兼容& 全兼容】

    更新时间 2020年9月18日 前言 博主自从写了这篇文章到现在 有好多友友来问我问题 以及我自己也在不断的尝试开发 现在我归纳一下从17年到现在我遇到的问题和友友们遇到的问题以及一些资料总结 资料 3 0开发包 https downloa
  • Java中的File与字符流,字节流

    File File类概述和构造方法 File 他是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于FIle而言 其封装的并不是一个真正存在的文件 仅仅是一个路径名而已 它可以是存在的 也可以是不存在的 将来是要通过
  • Java 统计连续签到天数

    说明 签到功能根据业务情况的不同大致分为两种 一种是只要进入系统就会默认签到 另外一种是进入系统之后需要用户手动点击签到按钮进行签到 两种情况最大的区别就是 自动签到连续签到天数肯定至少为1天 而手动签到的情况则需要考虑断签的情况 1 自动