Android how to get UTC Timezone offset even of negative timezone - java

Hi I am trying to send the UTC offset towards my server. So I am converting the device time zone into utc offset using following code
TimeZone tz = TimeZone.getDefault();
Calendar cal = GregorianCalendar.getInstance(tz);
int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
Log.d("UTC_Offset",offset);
Now i know as I am using the Math.abs it is not giving me the minus values but I am really dumb to know that how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
Note: I may be wrong about the offset thing in UTC but this solution I found on SO. Please let me know if there is any solution or also correct me if I am wrong in idea and its that UTC could not be in negative

Use SimpleDateFormat to format it for you:
String offset = new SimpleDateFormat("Z").format(new Date());
offset = offset.substring(0, 3) + ":" + offset.substring(3);
↓↓↓↓↓ IGNORE REST OF ANSWER IF IT IS CONFUSING ↓↓↓↓↓
Results when applying to all TimeZones in the Java VM:
-12:00
-11:00
-10:00
-09:30
-09:00
-08:00
-07:00
-06:00
-05:00
-04:00
-03:00
-02:30
-02:00
-01:00
+00:00
+01:00
+02:00
+03:00
+04:00
+04:30
+05:00
+05:30
+05:45
+06:00
+06:30
+07:00
+08:00
+08:45
+09:00
+09:30
+10:00
+10:30
+11:00
+12:00
+12:45
+13:00
+14:00
Java 8 code to print the above:
Instant now = Instant.now();
SimpleDateFormat fmt = new SimpleDateFormat("Z");
ZoneId.getAvailableZoneIds().stream()
.map(z -> ZoneId.of(z).getRules().getOffset(now))
.distinct()
.sorted(Comparator.reverseOrder())
.forEach(z -> {
fmt.setTimeZone(TimeZone.getTimeZone(z));
String offset = fmt.format(Date.from(now));
offset = offset.substring(0, 3) + ":" + offset.substring(3);
System.out.println(offset);
});

tl;dr
how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
ZoneId.of( "America/Tijuana" ).getRules().getOffset( Instant.now() ).getTotalSeconds()
-25200
No need to do the math yourself. We have classes for this: java.time.
For older Java before Java 8, use the ThreeTen-Backport library.
For older Android, see the ThreeTenABP project.
Avoid Date, Calendar, SimpleDateFormat, and TimeZone legacy classes.
Example:
org.threeten.bp.ZoneId
.systemDefault()
.getRules()
.getOffset​(
Instant.now()
)
.toString()
To get total seconds of that offset, call ZoneOffset::getTotalSeconds.
java.time
The modern approach uses the modern java.time classes. You are using terrible date-time classes that were years ago supplanted by java.time.
Get the offset-from-UTC of the computer’s current default time zone.
ZoneId z = ZoneId.systemDefault() ;
ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;
Notice that we passed a moment, represented as Instant object (a moment as seen in UTC). Politicians frequently change the offset used by the zone(s) of their jurisdiction. So the offset of your zone is likely to change over time. So you must specify a moment to ask for the offset that was in effect at that point in time.
Generate text representing that offset, using standard ISO 8601 format.
String output = offset.toString() ;
-07:00
When receiving such text, you can parse as a ZoneOffset object.
ZoneOffset offset = ZoneOffset.parse( "-07:00" ) ;
You asked:
that UTC could not be in negative
An negative offset means a place whose clocks run behind UTC. Generally, this means west (left) of the prime meridian, such as the Americas.
A positive offset means a place whose clocks run ahead of UTC. Generally, this means east (right) of the prime meridian, such as Europe, Africa, Asia.
Well, this is the commonly used meaning of positive & negative offsets, defined in the ISO 8601 standard. Some protocols and industries may use the opposite meaning. Always understand the intention of any data source you may be using.
how could I get the offset of those timezone who are in negative such as Tijuana which is GMT-07:00
ZoneId z = ZoneId.of( "America/Tijuana" ) ;
ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;
String output = offset.toString() ;
System.out.println( output ) ;
See this code run live at IdeOne.com.
-07:00
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

Related

Rrule Until tag data value

I'm working on a project which takes rrule to generate next occurrences. But I'm not able to understand what i need to put in UNTIL tag of rrule.
String str="RRULE:FREQ=MONTHLY;UNTIL=20190625T000000Z;INTERVAL=2;";
Idk how to convert date into "20190625T000000Z".I'm using rfc 2445 java library. If user enters the date as a string for example :25/06/2019......i need to set this value in UNTIL tag as shown above. If I set the default value in UNTIL then it works but not when i make it user friendly.. I'm taking all the values from user as start date, end date, interval, Byday,Until... But idk what value to set in UNTIL.
If someone can help.. Thanks in advance.
Parsing basic ISO 8601 format
Your input 20190625T000000Z is the “basic” variation of standard ISO 8601 format to represent a moment in UTC. The word “basic” means minimizing the use of delimiters (I do not recommend this, as it makes the string less readable by humans).
Defining a formatting pattern to match input.
String input = "20190625T000000Z";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmssX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );
Dump to console.
System.out.println("odt.toString(): " + odt);
See this code run live at IdeOne.com.
odt.toString(): 2019-06-25T00:00Z
Translating date to moment
If user enters the date as a string for example :25/06/2019......i need to set this value in UNTIL tag as shown above
First, parse that input string into a LocalDate, representing a date-only value, without time-of-day and without time zone.
DateTimeFormatter fDateOnly = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "25/06/2019" , fDateOnly );
ld.toString(): 2019-06-25
As for translating that date into a moment (a date with time-of-day in a zone or offset-from-UTC), that is trickier than it sounds intuitively.
A date such as the 25th of June 2019 represents an entire day. And a theoretical date at that. The moments when a day begins and ends varies around the globe by time zone. A new day begins much earlier in Tokyo Japan than in Paris France, and even later in Montréal Québec.
Another issue is that the day does not always begin at 00:00:00. Because of anomalies such as Daylight Saving Time (DST), the first moment of a day on some dates in some zones may be something like 01:00:00. Let the java.time classes determine first moment.
ZoneId z = ZoneId.of( "Africa/Tunis" );
ZonedDateTime zdt = ld.atStartOfDay( z );
zdt.toString(): 2019-06-25T00:00+01:00[Africa/Tunis]
That ZonedDateTime object represents a specific moment. But it uses the wall-clock time adopted by the people of a particular region (a time zone). Your goal is a moment in UTC. Fortunately, we can adjust from the zone to UTC by converting to an OffsetDateTime (a date and time with a context of offset-from-UTC rather than a time zone). We can specify UTC (an offset of zero) by the ZoneOffset.UTC constant.
OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC );
odt.toString(): 2019-06-24T23:00Z
Note how 00:00 on the 25th in Tunisia is 11 PM “yesterday” the 24th in UTC. Same moment, same simultaneous point on the timeline, but two different wall-clock times.
Lastly, we need a string in that “basic” ISO 8601 format. Use the same formatter we defined above.
DateTimeFormatter fIso8601DateTimeBasic = DateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmssX" );
String output = odt.format( fIso8601DateTimeBasic );
output: 20190624T230000Z
See this code run live at IdeOne.com.
Just what is the difference between a time zone and an offset-from-UTC? An offset is merely a number of hours-minutes-seconds. Nothing more, nothing less, just a number (well, three numbers). A time zone is much more. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region. For example, in most of North America, the offset changes twice a year, springing ahead an hour and then falling back an hour (the lunacy of Daylight Saving Time (DST)).
Tip: Date-time handling is surprisingly tricky and slippery. If you are working with calendars and the iCalendar spec for data exchange, I suggest you take a long while to study the concepts and practice with the industry-leading java.time classes.
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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Java SimpleDateFormat interprets 'z' differently on different OS

I've following code (simplified to focus on issue). That prints the timezone information using SimpleDateFormat pattern.
Do you know why z is treated differently on different machines ? And if there is a way to tell Java to treat it uniformly across all the machines ?
This class is being used in JavaMail and that is causing our email headers to include time which is not comply with RFC 2822.
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class DateFormatTest {
String PATTERN = "z";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(this.PATTERN);
public static void main(final String[] args) {
new DateFormatTest().printTimezone();
}
public void printTimezone() {
System.out.println(this.simpleDateFormat.format(Calendar.getInstance().getTime()));
}
}
Output : Windows / Mac
PDT
Output : Linux (CentOS Linux release 7.5.1804 (Core)) / Ubuntu 14 / 18
GMT-07:00
tl;dr
Never use Calendar. Use java.time classes instead.
For strings in RFC 1123 / RFC 822 format:
OffsetDateTime
.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )
Mon, 24 Sep 2018 23:45:21 GMT
To get the current offset-from-UTC in a particular time zone:
ZoneId
.systemDefault()
.getRules()
.getOffset(
Instant.now()
)
.toString()
-07:00
Avoid Calendar
You are using terrible old date-time classes that were supplanted years ago by the java.time. Never use those legacy classes; they are an awful wretched mess.
Your particular issue about Calendar behavior is moot as there is no need to ever be using that class again. Even when interoperating with old code not yet updated to java.time, you can convert easily between the legacy & modern classes via new methods added to the old classes.
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime() ;
…and…
GregorianCalendar gc = GregorianCalendar.from( zdt ) ;
java.time
Apparently you want the current offset-from-UTC for your current default time zone.
Get the current default time zone, a ZoneId.
ZoneId z = ZoneId.systemDefault() ; // Or specify ZoneId.of( "Pacific/Auckland" ) or so on.
Ask for the rules in that time zone.
ZoneRules rules = z.getRules() ;
Get the offset-from-UTC in effect in that zone at a certain moment. We will use the current moment, a Instant.
Instant now = Instant.now() ;
ZoneOffset offset = rules.getOffset( now ) ;
Generate a text representing that offset-from-UTC.
String output = "At " + now + " in zone " + z + " the offset is " + offset;
At 2018-09-24T23:38:44.192642Z in zone America/Los_Angeles the offset is -07:00
RFC 1123 / RFC 822
You mentioned an RFC but did not specify. Perhaps RFC 1123 / 822 ?
A formatter for that is built into java.time.
OffsetDateTime nowInUtc = OffsetDateTime.now( ZoneOffset.UTC ) ;
String output = nowInUtc.format( DateTimeFormatter.RFC_1123_DATE_TIME ) ;
Mon, 24 Sep 2018 23:45:21 GMT
ISO 8601
FYI, that RFC 1123 / RFC 822 format is a terrible format. It assumes English. It is difficult for machines to parse, and difficult for humans to read. But I understand that you may need it for outmoded old protocols.
Just know that modern protocols use ISO 8601 standard formats. Conveniently, these formats are used by default in the java.time classes when parsing/generating strings.
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Java: transform Long Timestamp + int offset to readable format

I'm trying to convert a Long timestamp with an offset (int) into a more readable format. So for example I have 1514564669355 as a timestamp with offset equal to 360. How should I go about transforming this into the equivalent date format using java?
In this case the timestamp would be stored in UTC, so with the offset I'm looking to converting it to whatever timezone it needs. Thanks for any help/tips.
Your Question is not clear.
Perhaps you mean you have a value in UTC and want to adjust it to an offset of 360 minutes ahead of UTC. (A poor way to communicate a moment in time.)
Or perhaps you meant the given value is already ahead of UTC. (An even worse way to communicate a moment in time.)
Starting with UTC
First parse your input number. We will assume that number is a count of milliseconds since the first moment of 1970 UTC, 1970-01-01T00:00Z.
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).
Instant instant = Instant.ofEpochMilli( 1_514_564_669_355L ) ;
instant.toString(): 2017-12-29T16:24:29.355Z
An offset-from-UTC is a number of hours, minutes, and seconds ahead of, or behind, UTC.
Perhaps your Question’s mention of an offset of 360 is meant to be 360 minutes, or 6 hours ahead of UTC.
The ZoneOffset class cannot be instantiated from a number of minutes over 59. So we convert from 360 minutes to a total number of seconds.
int seconds = ( int ) TimeUnit.MINUTES.toSeconds( 360L ) ; // Convert minutes to seconds.
ZoneOffset offset = ZoneOffset.ofTotalSeconds( seconds ); // Determine offset-from-UTC.
offset.toString(): +06:00
Adjust our Instant in UTC to this offset, yielding a OffsetDateTime object. Same moment, same point on the timeline, different wall-clock time. So the time-of-day is seen as 10 PM rather than as 4 PM since ( 16 + 6 ) = 22.
OffsetDateTime odt = instant.atOffset( offset );
odt.toString(): 2017-12-29T22:24:29.355+06:00
Starting with offset
Perhaps you meant the moment being communicated is a count of milliseconds from UTC but then the number of milliseconds in 360 minutes has already been added or subtracted.
By the way, this is a very bad way to exchange date-time values. Educate the supplier of your data about the ISO 8601 standard.
Let's undo that addition/subtraction of an offset, to get back to UTC.
long millisInOffset = TimeUnit.MINUTES.toMillis( 360L ); // Convert minutes to milliseconds.
long millisSinceEpoch = ( 1_514_564_669_355L - millisInOffset );
Instant instant = Instant.ofEpochMilli( millisSinceEpoch );
instant.toString(): 2017-12-29T10:24:29.355Z
See that value in the offset sent to us.
int seconds = ( int ) TimeUnit.MILLISECONDS.toSeconds( millisInOffset );
ZoneOffset offset = ZoneOffset.ofTotalSeconds( seconds );
OffsetDateTime odt = instant.atOffset( offset );
System.out.println( odt );
2017-12-29T16:24:29.355+06:00
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Java GregorianCalendar change TimeZone

I'm trying to set HOUR_OF_DAY field and change Timezone of the GregorianCalendar date object.
GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
date.set(Calendar.HOUR_OF_DAY, 23);
//date.get(Calendar.HOUR_OF_DAY);
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
Output:
HOUR: 16
HOUR: 23
For some reason value of HOUR_OF_DAY does not change after setting different timezone. But if I uncomment date.get for HOUR_OF_DAY, everything works exactly as it should
GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
date.set(Calendar.HOUR_OF_DAY, 23);
date.get(Calendar.HOUR_OF_DAY); // uncommenting this line will is changing the output
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
Output:
HOUR: 16
HOUR: 13
How is this possible? Why .get method is changing object behaviour?
The GregorianCalendar class inherits its get method from Calendar, which has the following side effect:
In lenient mode, all calendar fields are normalized.
This means that the time value and all fields are recomputed when get is called on a Calendar object. This can lead to some unpredictable behavior, particularly when coupled with setTimeZone, which has some documented buggy behavior of its own.
tl;dr
OffsetDateTime.now( ZoneOffset.ofHours( 10 ) ).withHour( 23 )
Avoid legacy date-time classes
The legacy date-time classes including GregorianCalendar are a confusing. awkward, poorly-design mess. Avoid them. Now supplanted by the java.time classes. Specifically, GregorianCalendar is replaced by ZonedDateTime.
Offset-from-UTC
You apparently want a moment with an offset-from-UTC of ten hours ahead of UTC. Define your desired offset.
ZoneOffset offset = ZoneOffset.ofHours( 10 ) ;
offset.toString(): +10:00
Get the current moment as an OffsetDateTime with that offset.
OffsetDateTime odt = OffsetDateTime.now( offset ) ;
odt.toString(): 2018-02-15T16:44:44.216642+10:00
You want to override the hour to be 23.
OffsetDateTime odt23 = odt.withHour( 23 ) ;
odt23.toString(): 2018-02-15T23:44:44.216642+10:00
Time zone
I'm trying to set HOUR_OF_DAY field and change Timezone of the GregorianCalendar date object.
Nope, you are changing the offset-from-UTC, not the time zone.
Always better to use a time zone rather than a mere offset, if you know for certain the intended zone. A time zone is a history of past, present, and future changes to the offset used by the people of a certain region. With a time zone you can always determine the offset, but not vice-versa.
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( "Australia/Brisbane" ) ;
Capture the current moment in a wall-clock time seen by the people of that zone.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Override the hour-of-day.
ZonedDateTime zdt23 = zdt.withHour( 23 ) ;
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.

Weird Date Format To Java Date

I got the following date format that I get from an API (Yes I tried to get them to change the API... dailywtf story):
\/Date(1310481956000+0200)\/
How can I convert this into a Java Date? (java.util.Date)
This comes from a .NET JSON web service.
Without knowing what the date/time string stands for, let me make a guess.
The 1310481956000 looks to be milliseconds after epoch, and the +0200 an offset relative to GMT.
The following code seem to indicate it as well:
final TimeZone tz = TimeZone.getTimeZone("GMT+0200");
final Calendar cal = Calendar.getInstance(tz);
cal.setTimeInMillis(1310481956000L);
final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
f.setTimeZone(tz);
System.out.println(f.format(cal.getTime()));
Prints 2011-07-12 16:45:56 GMT+02:00
How can I convert this into a Java Date? (java.util.Date)
First, get "them" to clearly and precisely tell you exactly what that date format means. (If they won't or can't you could guess; see below.)
Next write a custom parser to parse the String and extract the information content.
Finally, convert the information content into a form that matches one of the Date constructors and create an instance.
My guess is that the 1310481956000 part is the number of milliseconds since the UNIX epoch (1970/01/01T00:00) and that the 0200 represents a timezone offset of 2 hours (MET?). However, you shouldn't rely on a guess. Get "them" to give you the specification, or at least a number of examples and the actual times/timezones that they correspond to.
You'll have to get the format from the API provider but it seems like a epoch + an offset for time zones. To convert it you could try.
final String fromAPI = "1310481956000+0200"
final String epochTime = fromAPI.substring(0, fromAPI.indexOf("+"));
final String timeZoneOffSet = fromAPI.substring(fromAPI.indexOf("+"), fromAPI.size());
Date date = new Date(Long.parseLong(epochTime));
Notice i'm not doing anything with the time zone (if that's what it is). You'll have to deal with that but this should get you on the right path.
tl;dr
Instant.ofEpochMilli(
java.lang.Long.parseLong( "1310481956000" )
).atOffset( ZoneOffset.of( "+0200" ) )
Using java.time
The accepted Answer is correct but outdated. The modern way to handle this is through the java.time classes.
The input is ambiguous. Is it a count from the Unix epoch reference date-time of first moment of 1970 in UTC 1970-01-01T00:00:00:Z and then adjusted by two hours ahead of UTC? If so, this example code seen here works.
First parse that input number as a Instant. 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 the first portion of your string and parse as a long.
long millisSinceEpoch = java.lang.Long.parseLong( "1310481956000" );
Instant instant = Instant.ofEpochMilli( millisSinceEpoch );
instant.toString(): 2011-07-12T14:45:56Z
Extract the last portion of your string and parse as a ZoneOffset.
ZoneOffset offset = ZoneOffset.of( "+0200" );
Apply the offset to the Instant to get an OffsetDateTime.
OffsetDateTime odt = instant.atOffset( offset );
odt.toString(): 2011-07-12T16:45:56+02:00
Note that an offset-from-UTC is not a time zone. A zone is an offset plus a set of rules for handling anomalies such as Daylight Saving Time (DST).
Avoid java.util.Date whenever possible. But if you must use one, you can convert to/from java.time. Look to new conversion methods added to the old classes.
java.util.Date d = java.util.Date.from( odt.toInstant() );
d.toString(): Tue Jul 12 14:45:56 GMT 2011
See live code at IdeOne.com covering this entire example.
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?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.

Categories