Parsing formatted Date String in another TimeZone

2019-02-25 11:33发布

I am trying to convert a formatted date String to Date object. Date String is formatted to some other timezone.

When I do sdf.parse(String) it returns me my System date object.

Code is as below,

static Date convertGMTTime(String timeZone, long longDate){
    Date convertedTime = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    try{
        Date date = new Date(longDate);
        System.out.println("timezone: "+timeZone +", timestamp: "+date);
        Locale locale = Locale.ENGLISH;
        TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
        System.out.println("Source timezone: "+destTimeZone);
/*          DateFormat formatter = DateFormat.getDateTimeInstance(
                    DateFormat.DEFAULT,
                    DateFormat.DEFAULT,
                    locale);
        formatter.setTimeZone(destTimeZone);*/
        sdf.setTimeZone(destTimeZone);
        String convertedDateStr = sdf.format(date);
        System.out.println("convertedDateStr: "+convertedDateStr);
        convertedTime = sdf.parse(convertedDateStr);
        System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
    }catch(Exception e){
        e.printStackTrace();
    }
    return convertedTime;
}

I would appreciate if anyone could help and point out where I am going wrong. Thanks in advance.

Output:

timezone: Atlantic/Cape_Verde, timestamp: Tue Jun 26 17:38:11 IST 2012
Source timezone: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

convertedDateStr: 2012-06-26 11:08:11

convertedTime: Tue Jun 26 17:38:11 IST 2012
sdf:sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]


Some more details to share, When I use another sdf object(without setting timezone for it), It do return me correct time and date but still timezone is picked from System clock

Code

static Date convertGMTTime(String timeZone, long longDate){
    Date convertedTime = null;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdfParse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try{
        Date date = new Date(longDate);
        TimeZone destTimeZone = TimeZone.getTimeZone(timeZone);// TimeZone.getDefault();
        System.out.println("Source timezone: "+destTimeZone);
        sdf.setTimeZone(destTimeZone);
        String convertedDateStr = sdf.format(date);
        System.out.println("convertedDateStr: "+convertedDateStr );
        convertedTime = sdfParse.parse(convertedDateStr,new ParsePosition(0));
        System.out.println("convertedTime: "+convertedTime + "sdf: "+sdf.getTimeZone());
    }catch(Exception e){
        e.printStackTrace();
    }
    return convertedTime;
}

Output

Source timezone: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

convertedDateStr: 2012-06-26 12:24:56

convertedTime: Tue Jun 26 12:24:56 IST 2012 

sdf: sun.util.calendar.ZoneInfo[id="Atlantic/Cape_Verde",offset=-3600000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null]

I understand that when I do not assign timezone to sdf it takes System time zone, but why doesn't it show time in System time zone? I shows it in timezone as it was in String but Timezone is different.

Ans when I set timezone it returns date object as per my system time irrespective of the fact that sdf has some other time zone set.

Can anyone please explain the functional behavior for sdf.parse and sdf.format.

For me sdf.setTimeZone() does have its impact when we use format and it is nullified when we use sdf.parse(). I find it quite strange.

Appreciate help in this regard.

标签: java timezone
1条回答
干净又极端
2楼-- · 2019-02-25 11:47

You already have a Date (or the number of milliseconds of the Date), so there is nothing to convert. A Date doesn't have any time zone. It's a universal instant in time. The time zone is relevant only when you display this date, because the date 65647678000 could be 12:38 in some time zone, but 10:38 in some other time zone. It's also relevant when you parse the String representation of a Date, because 10:38 is 65647678000 in some time zone, but is 65657678000 in some other.

While you don't display a Date object, or parse a String to a Date, you don't need to care about time zones. And to choose the time zone used when displaying/parsing it, set the time zone of the DateFormat, and then use DateFormat.format()/DateFormat.parse() to format/parse the date.

When you use Date.toString() to display a date, it will always use your current time zone.

I find it easier to understand what I mean by not thinking of a Date as a day, a month, a year, an hour, etc., but as a moment: "when Kennedy was shot". "When Kennedy was shot" is the same moment for everyone. But if you represent the moment "when Kennedy was shot" in Dallas time zone, it's not the same result as the result you get when you represent this same moment in Paris time zone.

查看更多
登录 后发表回答