SimpleDateFormat不添加IST时区偏移量

时间:2017-01-12 15:59:15

标签: java simpledateformat

我正在尝试根据时区更正某个偏移值的日期。因此,当我使用时区偏移格式化时间戳时,我预计SimpleDateFormat会将偏移值添加到时间。
这是我试过的:

package com.krishna.mytrials;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateExperiments {

    public static void main(String[] args) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //Date we set in UI
        Date today = new Date();
        //The long value
        String todayBrowserLocalTimeStamp = sdf.format(today);
        System.out.println(todayBrowserLocalTimeStamp);
        Date todayBrowserLocalTimeStampDate = sdf.parse(todayBrowserLocalTimeStamp);
        System.out.println("Today's browser local time stamp: " + todayBrowserLocalTimeStampDate);
        System.out.println("And its long value:" + todayBrowserLocalTimeStampDate.getTime());
        System.out.println("Date generate from long:"+ new Date(todayBrowserLocalTimeStampDate.getTime()));
        //What server does to the above mid night time stamp of browser-local time zone
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        //What we get after it applied the server time zone to browser-local date
        //### This is the wrong date
        SimpleDateFormat sdf2 = new SimpleDateFormat();
        sdf2.setTimeZone(TimeZone.getTimeZone("GMT"));
        sdf2.applyPattern("yyyy-MM-dd HH:mm");
        System.out.println(sdf2.format(todayBrowserLocalTimeStampDate));
        String utcDateString = sdf.format(todayBrowserLocalTimeStampDate);
        System.out.println("The above mid night time stamp of browser-local time zone"
                + "is converted to GMT.### The wrong one:");
        System.out.println(utcDateString);
        //### The wrong date constructed
        Date utcDate = sdf.parse(utcDateString);
        System.out.println("###Wrong date:"+utcDate);
        //### The wrong long
        Long utcLong = utcDate.getTime();
        System.out.println("###Wrong long:"+utcLong);
        // What we will do with the GMT+05:30
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
        String dateToBeCorrected = sdf2.format(todayBrowserLocalTimeStampDate);
        System.out.println("Date to be corrected:"+ dateToBeCorrected);
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date correctedDate = sdf3.parse(dateToBeCorrected);
        System.out.println(correctedDate);
        SimpleDateFormat sdf4 = new SimpleDateFormat();
        sdf4.setTimeZone(TimeZone.getTimeZone("IST"));
        String correctedString = sdf4.format(correctedDate);
        System.out.println("Corrected date:" + formatDateToString(correctedDate,"dd MMM yyyy hh:mm:ss a", "IST"));


    }

    public static String formatDateToString(Date date, String format,
            String timeZone) {
        // null check
        if (date == null) return null;
        // create SimpleDateFormat object with input format
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        // default system timezone if passed null or empty
        if (timeZone == null || "".equalsIgnoreCase(timeZone.trim())) {
            timeZone = Calendar.getInstance().getTimeZone().getID();
        }
        // set timezone to SimpleDateFormat
        sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
        // return Date in required format with timezone as String
        return sdf.format(date);
    }


}
Here is the output:
2017-01-12
Today's browser local time stamp: Thu Jan 12 00:00:00 IST 2017
And its long value:1484159400000
Date generate from long:Thu Jan 12 00:00:00 IST 2017
2017-01-11 18:30
The above mid night time stamp of browser-local time zoneis converted to GMT.### The wrong one:
2017-01-11
###Wrong date:Wed Jan 11 05:30:00 IST 2017
###Wrong long:1484092800000
Date to be corrected:2017-01-11 18:30
Wed Jan 11 18:30:00 IST 2017
Corrected date:11 Jan 2017 06:30:00 PM
It is supposed add 05:30. to the date. What am I doing wrong?

1 个答案:

答案 0 :(得分:0)

您必须考虑使用格式化和解析的往返可能会丢失信息。这是因为格式化日期可能包含的信息少于原始Date实例所具有的信息。看看这个数据丢失:

原始时间戳(变量todayBrowserLocalTimeStampDate)为:2017-01-11 18:30(UTC)或长1484175600000L

String utcDateString = sdf.format(new Date(1484175600000L));
// 2017-01-11
Date utcDate = sdf.parse(utcDateString);

在这里删除时间部分并再次解析剥离的字符串。当然,生成的新Date - 实例也必须松开相应的时间部分,并且不能是和以前一样。

2017-01-11(零时间)将在5:30后在您的IST区域呈现,即:2017-01-11T05:30 + 05:30(记住:Date.toString()使用假设您的系统区域是您的IST区域。这与2017-01-11T00:00Z相同。一切都很好,只有你的期望用前缀###Wrong date表示的行是错误的。