• YYYY引起的思考


      平时格式化时间的时候一般都是用的yyyy-MM-dd ,年份都是小写y。最近看很多技术公众号上在发YYYY和yyyy的区别,特此总结一下:

    上代码,一目了然

    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    public class TestDate {
    
        public static void main(String[] args) {
    
            Calendar calendar = Calendar.getInstance();
            String []arr = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    
            calendar.set(2019, Calendar.AUGUST, 31);
    
            DateFormat formatUpperCase = new SimpleDateFormat("yyyy-MM-dd");
            DateFormat formatUpperCase2 = new SimpleDateFormat("YYYY-MM-dd");
            System.out.println("2019-08-31 to yyyy-MM-dd: " + formatUpperCase.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
            System.out.println("2019-08-31 to YYYY-MM-dd: " + formatUpperCase2.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
    
            calendar.set(2019, Calendar.DECEMBER, 31);
            System.out.println("2019-12-31 to yyyy-MM-dd: " + formatUpperCase.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
            System.out.println("2019-12-31 to YYYY-MM-dd: " + formatUpperCase2.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
    
            calendar.set(2019, Calendar.DECEMBER, 30);
            System.out.println("2019-12-30 to yyyy-MM-dd: " + formatUpperCase.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
            System.out.println("2019-12-30 to YYYY-MM-dd: " + formatUpperCase2.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
    
            calendar.set(2019, Calendar.DECEMBER, 29);
            System.out.println("2019-12-29 to yyyy-MM-dd: " + formatUpperCase.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
            System.out.println("2019-12-29 to YYYY-MM-dd: " + formatUpperCase2.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
    
            calendar.set(2019, Calendar.DECEMBER, 28);
            System.out.println("2019-12-28 to yyyy-MM-dd: " + formatUpperCase.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
            System.out.println("2019-12-28 to YYYY-MM-dd: " + formatUpperCase2.format(calendar.getTime())+",今天是:"+arr[calendar.get(Calendar.DAY_OF_WEEK)-1]);
    
        }
    }

    执行结果如下:

    2019-08-31 to yyyy-MM-dd: 2019-08-31,今天是:星期六
    2019-08-31 to YYYY-MM-dd: 2019-08-31,今天是:星期六
    2019-12-31 to yyyy-MM-dd: 2019-12-31,今天是:星期二
    2019-12-31 to YYYY-MM-dd: 2020-12-31,今天是:星期二
    2019-12-30 to yyyy-MM-dd: 2019-12-30,今天是:星期一
    2019-12-30 to YYYY-MM-dd: 2020-12-30,今天是:星期一
    2019-12-29 to yyyy-MM-dd: 2019-12-29,今天是:星期日
    2019-12-29 to YYYY-MM-dd: 2020-12-29,今天是:星期日
    2019-12-28 to yyyy-MM-dd: 2019-12-28,今天是:星期六
    2019-12-28 to YYYY-MM-dd: 2019-12-28,今天是:星期六

    注意上面标出的部分,发现2019-12-31 转化之后竟然变为了 2020年。

    查看SimpleDateFormat 的API,发现其实1.6版的并没有“Y” 这个参数,1.6版的参数如下:

            The following pattern letters are defined (all other characters from 'A' to 'Z' and from 'a' to 'z' are reserved):

    LetterDate or Time ComponentPresentationExamples
    G Era designator Text AD
    y Year Year 1996; 96
    M Month in year Month July; Jul; 07
    w Week in year Number 27
    W Week in month Number 2
    D Day in year Number 189
    d Day in month Number 10
    F Day of week in month Number 2
    E Day in week Text Tuesday; Tue
    a Am/pm marker Text PM
    H Hour in day (0-23) Number 0
    k Hour in day (1-24) Number 24
    K Hour in am/pm (0-11) Number 0
    h Hour in am/pm (1-12) Number 12
    m Minute in hour Number 30
    s Second in minute Number 55
    S Millisecond Number 978
    z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
    Z Time zone RFC 822 time zone -0800

    注意表格上面那句话,并不是只有以上表格中的字母被用到,事实上,其他字母也被预留了。发现上面的表格中并没有对“Y” 做格式定义。查找1.7版本

            The following pattern letters are defined (all other characters from 'A' to 'Z' and from 'a' to 'z' are reserved):

    LetterDate or Time ComponentPresentationExamples
    G Era designator Text AD
    y Year Year 1996; 96
    Y Week year Year 2009; 09
    M Month in year Month July; Jul; 07
    w Week in year Number 27
    W Week in month Number 2
    D Day in year Number 189
    d Day in month Number 10
    F Day of week in month Number 2
    E Day name in week Text Tuesday; Tue
    u Day number of week (1 = Monday, ..., 7 = Sunday) Number 1
    a Am/pm marker Text PM
    H Hour in day (0-23) Number 0
    k Hour in day (1-24) Number 24
    K Hour in am/pm (0-11) Number 0
    h Hour in am/pm (1-12) Number 12
    m Minute in hour Number 30
    s Second in minute Number 55
    S Millisecond Number 978
    z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
    Z Time zone RFC 822 time zone -0800
    X Time zone ISO 8601 time zone -08; -0800; -08:00

    发现"Y"是1.7版本新加的。新加的还有u,x。

    在测试纪元标志的过程中,发现了一个问题,然后又百度了一下定义,发现自己之前的认知是错误的。

    先说结论:

    1.世纪这个单位是从1开始,百结尾。比如一世纪,是公元1年~公元100年。再比如2000年是20世纪的最后一年,2001年是21世纪的第一年

    2.公元元年,也就是公元1年,公元元年之前的都是公元前,也就是公元1年的前一年是公元前1年。如果说公元1年是0001的话,那么从数字上来看0000就是公元前1年。实际上,在calendar中,year的最小值是1,而不是0,更不是负数。

    G的测试过程:

    G  公元,AD(Anno Domini)是公元,BC(Before Christ)代表公元前。需要注意的是在日期格式化中,没有一个日期是 0000年,0000年实际上是公元前1年。引用官方文档的另一个例子:"01/02/-3" is parsed as Jan 2, 4 BC.

            Calendar calendar = Calendar.getInstance();
            DateFormat formatUpperCase = new SimpleDateFormat("Gyyyy");
            calendar.set(Calendar.YEAR,2019);
            System.out.println(formatUpperCase.format(calendar.getTime()));

    结果:

    公元2019

    这里发现打印的并不是“AD” 或 “BC” ,而是“公元”。SimpleDateFormat初始化时,如果没有指定Locale,则会默认使用本地设置。修改一下构造方法,打印英文:

            Calendar calendar = Calendar.getInstance();
            DateFormat formatUpperCase = new SimpleDateFormat("Gyyyy", Locale.ENGLISH);
            calendar.set(Calendar.YEAR,2019);
            System.out.println(formatUpperCase.format(calendar.getTime()));

    结果:

    AD2019

    尝试一下公元前,发现如果只把年份设为负数,没有办法正确输出预想结果,单0可以

            Calendar calendar = Calendar.getInstance();
            DateFormat formatUpperCase = new SimpleDateFormat("Gyyyy");
            calendar.set(Calendar.YEAR,-2019);
            System.out.println(formatUpperCase.format(calendar.getTime()));

    结果:

    公元2020

    本来我们想打印公元前2020年,结果变成了公元2020年

    这里需要注意一下,Calendar中,不能直接用负数年份代表公元前(原因可以看Canlendar每个域的范围),纪元标志需要单独设置。  

            Calendar calendar = Calendar.getInstance();
            DateFormat formatUpperCase = new SimpleDateFormat("Gyyyy");
            calendar.set(Calendar.YEAR,2019);
            calendar.set(Calendar.ERA,GregorianCalendar.BC);
            System.out.println(formatUpperCase.format(calendar.getTime()));

    结果:

    公元前2019

    参考:https://mp.weixin.qq.com/s/LrtaTTz25NIV7EAr9q3BHQ

  • 相关阅读:
    02/Oct/2019:11:55:28 类型的时间转换为
    Flume 实时获取日志内容插入MySQL
    MySQL UTC时间转北京时间 | convert_tz()函数
    使用kettle实现循环
    python 获取系统环境变量 os.environ and os.putenv
    Python
    linux如何判断上一条命令执行是否正确
    局域网两台主机通过网络共享文件
    Kettle(Pentaho)实现web方式远程执行job或transformation
    kettle发送邮件 运行日志
  • 原文地址:https://www.cnblogs.com/andong2015/p/12189549.html
Copyright © 2020-2023  润新知