Java 2017年广告19:21:33.783,格林尼治标准时间+08:00[亚洲/香港]。如果要提醒用户何时保存时间,则ZonedDateTime将允许您在计算保存日期的时区中显示该信息 最后,OffsetDateTime也会起作用,但它似乎并没有给你其他两个的优势,所以我不会在这个选项上详细说明

Java 2017年广告19:21:33.783,格林尼治标准时间+08:00[亚洲/香港]。如果要提醒用户何时保存时间,则ZonedDateTime将允许您在计算保存日期的时区中显示该信息 最后,OffsetDateTime也会起作用,但它似乎并没有给你其他两个的优势,所以我不会在这个选项上详细说明,java,localdate,threetenbp,Java,Localdate,Threetenbp,由于一个瞬间在所有时区中都是相同的,因此在获取当前瞬间时不指定时区: final Instant currentDate = Instant.now(); 将3天添加到即时有点不同LocalDate,但其余逻辑是相同的: public static boolean hasDateExpired(int days, Instant savedDate, Instant currentDate) { boolean hasExpired = false; if(saved

由于一个瞬间在所有时区中都是相同的,因此在获取当前瞬间时不指定时区:

    final Instant currentDate = Instant.now();
将3天添加到
即时
有点不同
LocalDate
,但其余逻辑是相同的:

public static boolean hasDateExpired(int days, Instant savedDate, Instant currentDate) {
    boolean hasExpired = false;

    if(savedDate != null && currentDate != null) {
        /* has expired if the saved date plus the specified days is still before the current date (today) */
        if (savedDate.plus(days, ChronoUnit.DAYS).isBefore(currentDate)) {
            hasExpired = true;
        }       
    }

    return hasExpired;
}
另一方面,
ZonedDateTime
的使用与代码中的
LocalDate
完全相同:

    final ZonedDateTime currentDate = ZonedDateTime.now(ZoneId.of("Asia/Hong_Kong"));
如果要从程序运行的JVM获取当前时区设置,请执行以下操作:

    final ZonedDateTime currentDate = ZonedDateTime.now(ZoneId.systemDefault());
现在,如果您声明
public static boolean hasDateExpired(int days,ZonedDateTime savedDate,ZonedDateTime currentDate)
,您可以像前面一样执行以下操作:

        /* has expired if the saved date plus the specified days is still before the current date (today) */
        if (savedDate.plusDays(days).isBefore(currentDate)) {
            hasExpired = true;
        }       

即使两个
ZoneDateTime
对象位于两个不同的时区,也会执行正确的比较。因此,无论用户旅行到不同的时区,他/她在许可证到期前的时间不会少于或多于几个小时。

Hugo的答案和Ole V.V.的答案都是正确的,并且,时区对于确定当前日期至关重要

Period
这项工作的另一个有用的类是类。此类表示未附加到时间线的时间跨度,以年、月和日为单位

请注意,此类不适合表示此问题所需的已用时间,因为此表示“分块”为年、月和剩余天数。因此,如果使用
LocalDate.between(start,stop)
数周,结果可能类似于“两个月零三天”。请注意,由于这个原因,这个类没有实现
Compariable
接口,因为一对月份不能说比另一对月份大或小,除非我们知道涉及哪些特定月份

我们可以使用这个类来表示问题中提到的两天宽限期。这样做会使我们的代码更加自我记录。与其只传递整数,不如传递这种类型的对象

Period grace = Period.ofDays( 2 ) ;

LocalDate start = LocalDate.of( 2017 , Month.JANUARY , 23 ).plusDays( grace ) ;
LocalDate stop = LocalDate.of( 2017 , Month.MARCH , 7 ) ;
我们用来计算经过的天数

int days = ChronoUnit.DAYS.between( start , stop ) ;
持续时间
顺便说一下,该类类似于
Period
,因为它表示未附加到时间轴的时间跨度。但是
持续时间
表示总秒数加上以纳秒为单位解析的分数秒数。由此,您可以计算通用的24小时天数(非基于日期的天数)、小时、分钟、秒和分数秒。记住,一天并不总是24小时长;在美国,由于夏令时的原因,它们目前可能长达23、24或25小时

这个问题是关于以日期为基础的日子,而不是24小时。因此,
Duration
类在这里不合适


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • ,及以后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门为Android采用了ThreeTen Backport(如上所述)
该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,如、、和。

KISS

public static boolean hasDateExpired(int days, java.util.Date savedDate) {
    long expires = savedDate().getTime() + (86_400_000L * days);
    return System.currentTimeMillis() > expires;
}
在旧JRE上工作很好。Date.getTime()给出毫秒UTC,因此时区甚至不是一个因素。神奇的86'400'000是一天中的毫秒数


如果只使用long for savedTime,而不使用java.util.Date,则可以进一步简化此过程。

我构建了一个简单的实用程序类ExpiredDate,其中包含时区(如CET)、ExpiredDate、expireDays和differenceInHoursMillis

我使用java.util.Date和Date.before(expiredDate):

查看Date()乘以ExpireyDays加上(时区差乘以ExpireyDays)是否在expiredDate之前

任何早于到期日期的日期均为“到期”

通过添加(i)+(ii)创建新日期:

(i)。我使用一天中的毫秒数(day_in_MS=1000*60*60*24)乘以过期天数

+

(ii)。为了处理不同的时区,我找到默认时区(对于我来说是BST)和传入ExpiredDate的时区(例如CET)之间的毫秒数。对于CET,差值为一小时,即3600000毫秒。这将乘以过期天数

新日期从parseDate()返回

如果新日期在expiredDate之前->将expired设置为True。
dateTimeWithExpire.before(expiredDate)

我创建了3个测试:

  • 将到期日期设置为7天,到期日期=3

    未过期(7天大于3天)

  • 将到期日期/时间设置为2天

    未过期-因为CET时区在dateTimeWithExpire上增加了两个小时(每天一小时)

  • 将到期日期设置为1天,然后设置为到期日期
        final LocalDate currentDate = LocalDate.now(ZoneOffset.UTC);
    
        final Instant currentDate = Instant.now();
    
    public static boolean hasDateExpired(int days, Instant savedDate, Instant currentDate) {
        boolean hasExpired = false;
    
        if(savedDate != null && currentDate != null) {
            /* has expired if the saved date plus the specified days is still before the current date (today) */
            if (savedDate.plus(days, ChronoUnit.DAYS).isBefore(currentDate)) {
                hasExpired = true;
            }       
        }
    
        return hasExpired;
    }
    
        final ZonedDateTime currentDate = ZonedDateTime.now(ZoneId.of("Asia/Hong_Kong"));
    
        final ZonedDateTime currentDate = ZonedDateTime.now(ZoneId.systemDefault());
    
            /* has expired if the saved date plus the specified days is still before the current date (today) */
            if (savedDate.plusDays(days).isBefore(currentDate)) {
                hasExpired = true;
            }       
    
    Period grace = Period.ofDays( 2 ) ;
    
    LocalDate start = LocalDate.of( 2017 , Month.JANUARY , 23 ).plusDays( grace ) ;
    LocalDate stop = LocalDate.of( 2017 , Month.MARCH , 7 ) ;
    
    int days = ChronoUnit.DAYS.between( start , stop ) ;
    
    public static boolean hasDateExpired(int days, java.util.Date savedDate) {
        long expires = savedDate().getTime() + (86_400_000L * days);
        return System.currentTimeMillis() > expires;
    }
    
    package com.chocksaway;
    
    import java.text.ParseException;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class ExpiredDate {
        /**
         * milliseconds in a day
        */
        private static final long DAY_IN_MS = 1000 * 60 * 60 * 24;
        private String timeZone;
        private Date expiredDate;
        private int expireDays;
        private int differenceInHoursMillis;
    
        /**
         *
         * @param timeZone - valid timezone
         * @param expiredDate - the fixed date for expiry
         * @param expireDays - the number of days to expire
        */
        private ExpiredDate(String timeZone, Date expiredDate, int expireDays) {
            this.expiredDate = expiredDate;
            this.expireDays = expireDays;
            this.timeZone = timeZone;
    
            long currentTime = System.currentTimeMillis();
            int zoneOffset =   TimeZone.getTimeZone(timeZone).getOffset(currentTime);
            int defaultOffset = TimeZone.getDefault().getOffset(currentTime);
    
            /**
             * Example:
             *     TimeZone.getTimeZone(timeZone) is BST
             *     timeZone is CET
             *
             *     There is one hours difference, which is 3600000 milliseconds
             *
             */
    
            this.differenceInHoursMillis = (zoneOffset - defaultOffset);
        }
    
    
        /**
         *
         * Subtract a number of expire days from the date
         *
         * @param dateTimeNow - the date and time now
         * @return - the date and time minus the number of expired days
         *           + (difference in hours for timezone * expiryDays)
         *
         */
        private Date parseDate(Date dateTimeNow) {
            return new Date(dateTimeNow.getTime() - (expireDays * DAY_IN_MS) + (this.differenceInHoursMillis * expireDays));
        }
    
    
        private boolean hasDateExpired(Date currentDate) {
            Date dateTimeWithExpire = parseDate(currentDate);
    
            return dateTimeWithExpire.before(expiredDate);
        }
    
    
        public static void main(String[] args) throws ParseException {
    
            /* Set the expiry date 7 days, and expireDays = 3
            *
            * Not expired
            */
    
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DATE, -7);
    
            ExpiredDate expired = new ExpiredDate("CET", cal.getTime(), 3);
    
            Date dateTimeNow = new Date();
    
            if (expired.hasDateExpired(dateTimeNow)) {
                System.out.println("expired");
            } else {
                System.out.println("NOT expired");
    
            }
    
            /* Set the expiry date / time, and expireDays to 2 days
             *  Not expired - because the CET timezone adds two hours to the dateTimeWithExpire
            */
    
    
            cal = Calendar.getInstance();
            cal.add(Calendar.DATE, -2);
    
            expired = new ExpiredDate("CET", cal.getTime(), 2);
    
            dateTimeNow = new Date();
    
            if (expired.hasDateExpired(dateTimeNow)) {
                System.out.println("expired");
            } else {
                System.out.println("NOT expired");
    
            }
    
            /* Set the expiry date 1 days, and expireDays = 2
            *
            * expired
            */
    
            cal = Calendar.getInstance();
            cal.add(Calendar.DATE, -1);
    
            expired = new ExpiredDate("CET", cal.getTime(), 2);
    
            dateTimeNow = new Date();
    
            if (expired.hasDateExpired(dateTimeNow)) {
                System.out.println("expired");
            } else {
                System.out.println("NOT expired");
    
            }
    
         } 
     }
    
    package com.chocksaway;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.TimeZone;
    
    public class ExpiredDate {
        private static final long DAY_IN_MS = 1000 * 60 * 60 * 24;
    
        private static boolean hasDateExpired(int days, java.util.Date savedDate) throws ParseException {
            SimpleDateFormat dateFormatUtc = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
            dateFormatUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
    
            // Local Date / time zone
            SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    
            // Date / time in UTC
            savedDate = dateFormatLocal.parse( dateFormatUtc.format(savedDate));
    
            Date dateTimeNow = dateFormatLocal.parse( dateFormatUtc.format(new Date()));
    
            long expires = dateTimeNow.getTime() + (DAY_IN_MS * days);
    
            Date expiresDate = new Date(expires);
    
            System.out.println("savedDate \t\t" + savedDate + "\nexpiresDate \t" + expiresDate);
    
            return savedDate.before(expiresDate);
        }
    
        public static void main(String[] args) throws ParseException {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DATE, 0);
    
            if (ExpiredDate.hasDateExpired(-2, cal.getTime())) {
                System.out.println("expired");
            } else {
                System.out.println("not expired");
            }
    
            System.out.print("\n");
    
            cal.add(Calendar.DATE, -3);
    
            if (ExpiredDate.hasDateExpired(-2, cal.getTime())) {
                System.out.println("expired");
            } else {
                System.out.println("not expired");
            }
        }
    }
    
    savedDate       Mon Jun 05 15:03:24 BST 2017
    expiresDate     Sat Jun 03 15:03:24 BST 2017
    not expired
    
    savedDate       Fri Jun 02 15:03:24 BST 2017
    expiresDate     Sat Jun 03 15:03:24 BST 2017
    expired