StringDate to Date在Java中的SimpleDateFormat中出现在不同的时间 [英] StringDate to Date coming in different Time in SimpleDateFormat in java

查看:91
本文介绍了StringDate to Date在Java中的SimpleDateFormat中出现在不同的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

    /*I want the same Date of my String has
     Tried with couple of options but nothing worked 
     pasting some of code here */

    public void stringToDate() {

        //Current format "13-FEB-20 03.21.08.100000000 PM" in Melbourne Timezone
        //Required Format yyyy-dd-MM HH:mm:ss.SSS in Melbourne Timezone

        String inputAM = "13-FEB-20 03.21.08.100000000 PM";
        try {
            DateFormat df1 = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa");
            Date d1 = df1.parse(inputAM);
            System.out.println("Date-1: " + d1); //Fri Feb 14 19:07:48 AEDT 2020

            DateFormat df2 = new SimpleDateFormat("DD-MMM-yy hh.mm.ss.S aa");
            Date d2 = df2.parse(inputAM);
            System.out.println("Date-2: " + d2); //Tue Jan 14 19:07:48 AEDT 2020

        } catch (ParseException e) {
            e.printStackTrace();
        }

        SimpleDateFormat etDf = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss.SSS");
        TimeZone etTimeZone = TimeZone.getTimeZone("Australia/Melbourne");
        etDf.setTimeZone(etTimeZone);

        DateFormat df3 = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.SSSSSSSSS a");
        Date d3;
        try {
            d3 = df3.parse(inputAM);
            System.out.println("Date-3: " + d3); //Fri Feb 14 07:07:48 AEDT 2020
            System.out.println("Date-4: " + etDf.format(d3.getTime())); //2020-14-02 07:07:48.000
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

推荐答案

首先,在大多数情况下,请勿将日期和时间从一种字符串格式转换为另一种字符串格式.在程序中,将日期和时间保留为正确的日期时间对象,而不是字符串.当您接受字符串输入时,首先要解析它.仅在需要输出字符串时,才将日期时间格式化为所需格式的字符串.

First, for most purposes don’t convert a date and time from one string format to another. In your program keep date and time as proper date-time objects, not strings. When you accept string input, parse it first thing. Only when you need to give string output, format your date-time into a string in the required format.

第二,对所有的日期和时间工作使用现代的Java日期和时间API java.time.与旧的,设计欠佳且过时的类(包括DateFormatSimpleDateFormatDate)相比,使用它要好得多.

Second, use java.time, the modern Java date and time API for all of your date and time work. It is so much nicer to work with than the old, poorly designed and long outdated classes including DateFormat, SimpleDateFormat and Date.

    //Current format "13-FEB-20 03.21.08.100000000 PM" in Melbourne Timezone
    DateTimeFormatter currentFormatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("d-MMM-uu hh.mm.ss.SSSSSSSSS a")
            .toFormatter(Locale.ENGLISH);
    ZoneId zone = ZoneId.of("Australia/Melbourne");

    String inputAM = "13-FEB-20 03.21.08.100000000 PM";

    ZonedDateTime dateTime = LocalDateTime.parse(inputAM, currentFormatter).atZone(zone);

    System.out.println(dateTime);

到目前为止的输出是:

2020-02-13T15:21:08.100 + 11:00 [澳大利亚/墨尔本]

2020-02-13T15:21:08.100+11:00[Australia/Melbourne]

使用java.time格式化

    //Required Format yyyy-dd-MM HH:mm:ss.SSS in Melbourne Timezone
    DateTimeFormatter requiredFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
    String formatted = dateTime.format(requiredFormatter);
    System.out.println(formatted);

2020-02-13 15:21:08.100

2020-02-13 15:21:08.100

您的代码出了什么问题?

当我第一次尝试使用您的代码时,FEB的解析失败,因为您的代码未指定语言环境,而我的Java使用的是非英语的默认语言环境.

What went wrong in your code?

When I first tried your code, parsing failed for FEB because your code doesn’t specify locale, and my Java uses a non-English default locale.

更正我能够解析该字符串并获得与您相同的结果(仅在我的时区中).会发生什么:SimpleDateFormat将大写字母S表示为毫秒,即1000秒,无论要解析的字符串中有多少S和多少位数.因此,您的日期和时间增加了1亿毫秒.超过一天.因此,您得到了2月14日而不是2月13日,而且一天中的时间也不正确.与现代的DateTimeFormatter大写字母S表示第二部分的分数一样,因此它以我们期望的方式处理SSSSSSSSSSSS.

Correcting that I was able to parse the string and got the same results as you (only in my time zone). What happens: SimpleDateFormat takes uppercase S to mean milliseconds, 1000ths of seconds, no matter how many S there are and no matter how many digits are in the string to be parsed. So 100 000 000 milliseconds were added to your date and time. That’s a little more than one day. So you got 14 Feb instead of 13 Feb, and also a wrong time of day. In contrast to the modern DateTimeFormatter upper case S means fraction of second, so it handles both SSSSSSSSS and SSS the way we expect.

大写字母DD是一年中的一天,因此使用它来解析一年中的第13天(与1月13日相同)加上100000秒.

Uppercase DD is for day of year, so using this for parsing you got the 13th day of the year (the same as 13 January) plus your 100 000 seconds.

大写字母HH是一天中从00到23的小时.使用HH进行解析会给您一天中的03:21(与03:21 AM相同)加上您的100000秒,无论它说的是PM在您的字符串中.

Uppercase HH is for hour of day from 00 through 23. Parsing using HH gave you 03:21 of day (same as 03:21 AM) plus your 100 000 seconds no matter that it said PM in your string.

  • Oracle tutorial: Date Time explaining how to use java.time.

这篇关于StringDate to Date在Java中的SimpleDateFormat中出现在不同的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆