调试与日历日期 GMT 相关的简单 java 代码

Posted

技术标签:

【中文标题】调试与日历日期 GMT 相关的简单 java 代码【英文标题】:Debug simple java code related to Calendar Date GMT 【发布时间】:2011-08-21 13:26:08 【问题描述】:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class Test 

    public static void main(String[] args) throws ParseException 

        Calendar dateFromNet = strToCal("11-MAR-2004", "dd-MMM-yyyy");
        Calendar IEndTime = strToCal("20-05-2004", "dd-mm-yyyy");

        if (dateFromNet.after(IEndTime) ) 

            System.out.println(dateFromNet);
            System.out.println(IEndTime);

            System.out.println("not true: 11-MAR-2004(11-3-2004) > 20-05-2004 ");
        


    

    private static Calendar strToCal(String date, String format) throws ParseException 
        SimpleDateFormat input = new SimpleDateFormat(format);
        input.setTimeZone(TimeZone.getTimeZone("GMT"));

        Date d = (Date) input.parse(date);
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        return c;
    

这个测试显示

dateFromNet.after(IEndTime) == true

即11-03-2004 是在 20-05-2004 之后

我做错了什么?

【问题讨论】:

【参考方案1】:
Calendar IEndTime = strToCal("20-05-2004", "dd-mm-yyyy");

mm 是毫秒;制作那些国会大厦 M,像这样:

Calendar IEndTime = strToCal("20-05-2004", "dd-MM-yyyy");

【讨论】:

【参考方案2】:

字母mM有不同的含义,如下表所示:

Letter Date or Time Component Presentation Examples
m Minute in hour Number 30
M Month in year Month July; Jul; 07

所以,问题的根本原因是在模式dd-mm-yyyy 中使用m 而不是M

java.time

旧的日期时间 API(java.util 日期时间类型及其格式类型,SimpleDateFormat)已过时且容易出错。建议完全停止使用,改用java.time,modern date-time API*

现代 API 演示:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main 
    public static void main(String[] args) 

        ZonedDateTime dateFromNet = strToZdt("11-MAR-2004", "d-MMM-u");
        ZonedDateTime IEndTime = strToZdt("20-05-2004", "d-M-u");

        if (dateFromNet.isAfter(IEndTime)) 
            System.out.println("11-MAR-2004 > 20-05-2004");
         else if (dateFromNet.isBefore(IEndTime)) 
            System.out.println("11-MAR-2004 < 20-05-2004");
         else 
            System.out.println("11-MAR-2004 = 20-05-2004");
        
    

    private static ZonedDateTime strToZdt(String date, String format) 
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseCaseInsensitive()
                                .appendPattern(format)
                                .toFormatter(Locale.ENGLISH);

        LocalDate localDate = LocalDate.parse(date, dtf);

        return localDate.atStartOfDay(ZoneId.of("Etc/UTC"));
    

输出:

11-MAR-2004 < 20-05-2004

如果您需要从ZonedDateTime 的对象中获得java.util.Calendar 的对象,您可以按如下方式进行:

Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(dateFromNet.toInstant()));

通过 Trail: Date Time 了解有关 modern date-time API* 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。

【讨论】:

以上是关于调试与日历日期 GMT 相关的简单 java 代码的主要内容,如果未能解决你的问题,请参考以下文章

java日历/格式提供错误的日期

GMT 与 UTC 日期

如何使用 Java 处理日历时区?

JAVA编写简单的日历,输入日期即可查看日历

用java编辑日历记事本

Java 日期与日历