How to get local date time for timezone - java

Here is the problem
I get the data from API as
curl "http://api.timezonedb.com/?lat=53.7833&lng=-1.75&key=OXFVZEHUDERF&format=json"
{"status":"OK","message":"","countryCode":"GB","zoneName":"Europe\/London","abbreviation":"BST","gmtOffset":"3600","dst":"1","timestamp":1442983759}Harits-MacBook-Pro-2:~ harit$ curl "http://api.timezonedb.com/?lat=-44.490947&lng=171.220966&key=API_KEY&format=json"
and result as
{"status":"OK","message":"","countryCode":"NZ","zoneName":"Pacific\/Auckland","abbreviation":"NZST","gmtOffset":"43200","dst":"0","timestamp":1443023417}
As per their docs, the timestamp is
Current local time in Unix timestamp.
How do I print it as
2013-07-10T14:52:49
in that timezone Europe/London ?

Though you have not mentioned but you can achieve it in java 8 like:
public static void main(String[] args) throws IOException {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
final long unixTime = 1443023417;
final String formattedDtm = Instant.ofEpochSecond(unixTime).atZone(ZoneId.of("PLT")).format(formatter);
System.out.println(formattedDtm);
}
It prints:
2015-09-23 11:50:17
Java 8 introduces the Instant.ofEpochSecond method for creating an Instant from a Unix timestamp which can then be converted to a ZonedDateTime and then can be formatted as per your requirement.

Since you have the timezone as well timestamp, you can get LocalDateTime as
LocalDateTime lt = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.of(ZoneId.SHORT_IDS.get("BST")));
System.out.println(lt);

Related

How to convert java.util.Date to soap suppported date format "yyyy-MM-dd'T'HH:mm:ss" with zone id

I am dealing with a situation where I want to convert java.util date into soap supported format with specific zone (Europe/Brussels)
I tried using Java 8 zone id feature but it seems it works well with instant dates only.
ZoneId zoneId = ZoneId.of("Europe/Brussels");
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(Instant.now(),
zoneId);
GregorianCalendar calendar = GregorianCalendar.from(zonedDateTime);
String xmlNow = convertToSoapDateFormat(calendar);
calendar.add(Calendar.MINUTE, 61);
String xmlLater = convertToSoapDateFormat(calendar);
//Method for soap conversion
private String convertToSoapDateFormat(GregorianCalendar cal) throws DatatypeConfigurationException {
XMLGregorianCalendar gDateFormatted2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(
cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH),
cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND),
DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
return gDateFormatted2.toString();// + "Z";
}
I want lets say this date (2002-02-06) converted to this SOAP format 2002-02-06T08:00:00
You can use the SimpleDateFormat class with setTimezone method
public class Main {
public static void main(String[] args) {
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-MM-yyyy'T'HH:mm:ss");
sdfAmerica.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
String sDateInAmerica = sdfAmerica.format(new Date());
System.out.println(sDateInAmerica);
}
}
I'm not sure if this is the answer you are looking for, so tell me if I misunderstood your question. Then I'll delete the answer.
You can use the SimpleDateFormat class to achieve your goal. Create the format with by
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
And then format the date with the following call:
df.format(date);
java.time
I tried using Java 8 zone id feature but it seems it works well with
instant dates only.
Using java.time, the modern Java date and time API that came out with Java 8 and includes ZoneId, certainly is the recommended approach. And it works nicely. I cannot tell from your question what has hit you. If I understand correctly, DateTimeFormatter.ISO_OFFSET_DATE_TIME will give you the format you are after for your SOAP XML.
ZoneId zoneId = ZoneId.of("Europe/Brussels");
ZonedDateTime zdtNow = ZonedDateTime.now(zoneId);
String xmlNow = zdtNow.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
ZonedDateTime zdtLater = zdtNow.plusMinutes(61);
String xmlLater = zdtLater.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println("Now: " + xmlNow);
System.out.println("Later: " + xmlLater);
When I ran this code just now, the output was:
Now: 2019-10-21T13:56:37.771+02:00
Later: 2019-10-21T14:57:37.771+02:00

Why do i get in the Date arrivalMuseum +7 Hours?

When i bring time from ZonedDateTime to Date I get the time increased exactly 7 hours in arrivalMuseum. What is the reason?
public static String determine(final String departureTime, final String city)
throws ParseException {
final ZoneId leavingZone = ZoneId.of("Europe/Minsk");
final ZonedDateTime departure = ZonedDateTime.of(LocalDateTime.parse(departureTime),
leavingZone);
final ZoneId arrivingZone = ZoneId.of("Europe/London");
final ZonedDateTime arrival = departure.withZoneSameInstant(arrivingZone).plusMinutes(270);
final Instant instant = arrival.toInstant();
final Date arrivalMuseum = Date.from(instant);
}
There is a reason why Date is only compatible with the Instant class of the java.time package. This is because it only deals with the date in your personal timezone.
So when you print the arrivalMuseum object it gets automatically converted to whatever timezone you are currently in. Given the time difference of 7 hours this is probably UTC+8.
If you really need to use the old API you will need to use the Calendar api to get a date formatted for a specific timezone, but there are reasons a new date/time API was created and dealing with other timezones is one of them.

Get locale specific date/time format in Java

I have use case in java where we want get the locale specific date. I am using DateFormat.getDateInstance
final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM,
Locale.forLanguageTag(locale)));
This translates the dates but ja-JP this translates the date "17 January 2019" to "2019/01/17" but I need something like "2019年1月17日". For all other locales this correctly translates the date.
Please let know if there is other method to get this.
This worked for me:
public static void main(String[] args) throws IOException {
final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.JAPAN);
Date today = new Date();
System.out.printf("%s%n", dateFormat.format(today));
}
and MEDIUM acted exactly how you said
UPD: or using newer ZonedDataTime as Michael Gantman suggested:
public static void main(String[] args) throws IOException {
ZonedDateTime zoned = ZonedDateTime.now();
DateTimeFormatter pattern = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.JAPAN);
System.out.println(zoned.format(pattern));
}
Just to mention: SimpleDateFormat is an old way to format dates which BTW is not thread safe. Since Java 8 there are new packages called java.time and java.time.format and you should use those to work with dates. For your purposes you should use class ZonedDateTime Do something like this:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("..."));
to find out correct zone id for Japan use
ZoneId.getAvailableZoneIds()
Later on to format your Date correctly use class DateTimeFormatter
The trick is to use java.time.format.FormatStyle.LONG:
jshell> java.time.format.DateTimeFormatter.ofLocalizedDate(java.time.format.FormatStyle.LONG).withLocale(java.util.Locale.JAPAN)
$13 ==> Localized(LONG,)
jshell> java.time.LocalDate.now().format($13)
$14 ==> "2019年1月17日"

How do I convert a DateTime with the GMT offset to UTC in Java?

I receive this DateTime from a payload: 2016-09-18T11:00:00.000-04:00.
I want to convert it to UTC. I know I just need to take the offset and modify the hours based on that, but I can't find the syntax to do this using the input in the format it is given to me.
Expected Result: 2016-09-18T15:00:00.000
Your input is in ISO format, so with Java 8+ it's fairly simple:
OffsetDateTime dateTime = OffsetDateTime.parse("2016-09-18T11:00:00.000-04:00");
OffsetDateTime utc = dateTime.withOffsetSameInstant(ZoneOffset.UTC); //2016-09-18T15:00Z
I was able to do this using SimpleDateFormat:
public static void main(String[] args) throws Exception {
SimpleDateFormat iso_8601_format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = iso_8601_format.parse("2016-09-18T11:00:00.000-04:00");
iso_8601_format.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(iso_8601_format.format(date));
}
This results in the following output:
2016-09-18T15:00:00.000Z
The literal 'Z' at the end is indicative of "Z"ero offset, or UTC. You could manually strip that off if you need to, but if you are using ISO 8601 as your format of choice, either is valid.

Setting default year in Joda Time

I am currently using the joda dateTime Api in my application. I am using the following code to parse multiple formats of dates into one single format. I am having trouble though when the format does not have a year. currently it sets the year as "2000".
Is there a way to set the year to a default if it is missing?
private static final DateTimeParser[] parsers = {
DateTimeFormat.forPattern("dd/MMM/yyyy:HH:mm:ss Z").getParser(),
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").getParser(),
DateTimeFormat.forPattern("[dd/MMM/yyyy:HH:mm:ss Z]").getParser(),
DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").getParser(),
DateTimeFormat.forPattern("MMM-dd HH:mm:ss,SSS").getParser()
};
public static DateTime ConvertDate(String timestamp) {
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter();
DateTime date = formatter.parseDateTime(timestamp);
return date;
}
example:
Mar-07 13:59:13,219
becomes
2000-03-07T12:59:13.219-07:00
what I want :
example:
Mar-07 13:59:13,219
becomes
(currentyear)-03-07T12:59:13.219-07:00
You can use withDefaultYear():
public static DateTime convertDate(String timestamp) {
int stdYear = 1970; // example for new default year
DateTimeFormatter formatter =
new DateTimeFormatterBuilder().append(null, parsers).toFormatter()
.withDefaultYear(stdYear);
return formatter.parseDateTime(timestamp);
}
Since Joda 2.0 the default year is 2000 so that Feb 29 could be parsed correctly, check this.
Not sure if you can change that (check this with pivotYear), but as a bypass solution I would add current year to my timestamp if there wasn't any.

Categories