SimpleDateFormat returns wrong time zone during parse
Asked Answered
B

3

4

I am facing a strange problem during the creation of Date object. I have the below code to set the time zone of the date to UTC. Before the parse statement i see that sdfDate has time zone as UTC but after the parse statement i see that punchDate has value: Sat Mar 30 01:00:00 CET 2013, this i believe is coming from my system. But how do i make sure that the time zone remains same even after parse.

Date punchDate = null;
Date punchTime = null;

SimpleDateFormat sdfDate = new SimpleDateFormat("dd.MM.yyyy");
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");

    try
    {
        sdfDate.setTimeZone(TimeZone.getTimeZone("UTC"));
        sdfTime.setTimeZone(TimeZone.getTimeZone("UTC"));
        punchDate = sdfDate.parse(arg1);
        punchTime = sdfTime.parse(arg2);
    }
    catch (ParseException pe)
    {
        System.out.println("Parse exception " +pe.getMessage());
    }

My requirement is basically that i need to make a Date Object from String input but the time zone should remain UTC.

Balthazar answered 19/4, 2013 at 15:15 Comment(0)
T
3

tl;dr

i need to make a Date Object from String input but the time zone should remain UTC.

LocalDate.parse( 
    "23.01.2017" , 
    DateTimeFormatter.ofPattern( "dd.MM.uuuu" ) 
) 

…and…

LocalTime.parse( "12:34:56" ) 

…combine…

OffsetDateTime.of( datePart , timePart , ZoneOffset.UTC )

Details

You are using troublesome confusing old date-time classes that are now supplanted by the java.time classes.

OffsetDateTime

You say you are certain that your inputs were intended for UTC despite no such indicator. So we will parse the date portion, parse the time-of-day portion, and then combine while assigning an offset-from-UTC of zero for UTC.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu" ) ;
LocalDate ld = LocalDate.parse( "23.01.2017" , f ) ;

The time-of-day input happens to comply with standard ISO 8601 formatting used by default in the java.time classes. So no need to specify a formatting pattern.

LocalTime lt = LocalTime.parse( "12:34:56" ) ;

Combine.

OffsetDateTime odt = OffsetDateTime.of( ld , lt , ZoneOffset.UTC ) ;

Time zone

If you want to see that same moment as presented in the wall-clock time of a particular region, apply a ZoneId to get a ZonedDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;  // Same simultaneous moment, same point on the timeline.

ISO 8601

Tip: To exchange this kind of data as text, use the standard ISO 8601 formats exclusively. These formats are sensibly designed to be unambiguous, easy to process by machine, and easy to read across many cultures by people.

The java.time classes use the standard formats by default when parsing and generating strings.

String output = Instant.now().toString() ;  

2017-01-23T12:34:56.123456789Z

Convert

Avoid the legacy java.util.Date class. But if you must, you can convert. Look to new methods added to the old classes.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Extract an Instant object from your OffsetDateTime by calling toString.

Instant instant = odt.toInstant() ;
java.util.Date date = Date.fromInstant( instant ) ;

…going the other way…

Instant instant = myJavaUtilDate.toInstant() ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;  

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Tetanus answered 4/9, 2017 at 0:43 Comment(0)
K
1

It is very tricky to maintain the timeZone and parse a string to Date. Finally figured out this way that worked for me.

SimpleDateFormat sdfDate = new SimpleDateFormat("dd.MM.yyyy");

var formattedString = DateFormatUtils.format(startDate, "dd.MM.yyyy",TimeZone.getTimeZone("UTC"));
Date parsedDate = simpleDateFormat.parse(formattedString);

Now the parsedDate will have a Date in specified format but is not effected with the JVM's default TimeZone.

Krp answered 11/7, 2023 at 16:38 Comment(1)
This is redundant but, using sdfDate for both format and parse doesn't seem to be working, as you need to set the TimeZone for sdfDate inorder to format, and that will effect parse.Krp
T
0

Your Date Object woule be same with respect to your local system time. You have created with local date object with local timezone and while assigning converted(UTC) timezone to local.

Date punchDate = null;
Date punchTime = null;

so your date value remain same but it shows in different timezone value.

Trapes answered 22/9, 2015 at 9:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.