joda time, DateTimeFormatter - java

I have following code
dateTimeFormat = ISODateTimeFormat.dateTimeNoMillis()
and i use dateTimeFormat below
public static String print(Date value) {
return dateTimeFormat.print(value.getTime());
}
And now i get problem, in my print method i put many date instances with + 4 hours time, and after dateTimeFormat.print(value.getTime()); i get time with +3 hour, but one of all date instances become with +4 hours, this error for me.
In all date instances has the same time zone Europe/Moscow
What may be wrong in my case?

In all date instances has the same time zone Europe/Moscow
A Date instance doesn't have a time zone - it's just an instant in time. But you should probably specify the time zone for your formatter, e.g.
dateTimeFormat = ISODateTimeFormat
.dateTimeNoMillis()
.withZoneUTC();
If you want a value which does know about a time zone, you should use DateTime instead of Date.

java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println(print(new Date()));
}
public static String print(Date value) {
return value.toInstant()
.atZone(ZoneId.of("Europe/Moscow"))
.truncatedTo(ChronoUnit.SECONDS)
.toOffsetDateTime()
.toString();
}
}
Output:
2021-06-20T16:18:56+03:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Related

String to Date in Java

I have a date string like this "2010-12-10T20:03:53-06:00"
I want to convert the same into equivalent date object in Java.
Any Idea how to do this?
What you are looking for is SimpleDateFormat.parse(). It will convert a string into a Date object.
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
If you're using Java 7, you should be okay without any string massaging, using the new X specifier for the UTC offset:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.US);
Date date = format.parse(text);
(Testing to make sure - when I've installed JDK 7 myself :)
In general I would strongly recommend using Joda Time for date handling, however. Its Z specifier can handle an offset with a colon:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ")
.withLocale(Locale.US);
DateTime dateTime = formatter.parseDateTime(text);
In fact, there's an ISODateTimeFormat class to make this even simpler:
DateTimeFormatter formatter = ISODateTimeFormat.dateTimeNoMillis();
Joda Time is a significantly better date/time API than the built-in one. (It's far from perfect, but it's a lot better than Date and Calendar...)
You should use DateFormat class for this:
First you need to get rid of that : in the timezone part and make your date string like this
2010-12-10T20:03:53-0600
and use the code snippet below:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = formatter.parse("2010-12-10T20:03:53-0600");
Note: I checked this on Java 6 and Mr. Skeet has mentioned a better answer dealing with Java 7 as I don't know more about Java 7
Use Joda time. It is powerful and easy to use.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
Demo:
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.parse("2010-12-10T20:03:53-06:00");
System.out.println(odt);
}
}
Output:
2010-12-10T20:03:53-06:00
ONLINE DEMO
For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
You can't parse a date with a colon in the time zone with the standard JDK Date until Java 7. Before Java 7 timezone would have to be either a full time zone with name or in the form -0600.
You have 3 options:
if you use Java 7+, use this pattern: "yyyy-MM-dd'T'HH:mm:ssX" with a SimpleDateFormat
manually remove the colon and parse
use Joda Time, for example: https://stackoverflow.com/a/2375539/829571
Here is an example with the second option:
public static void main(String[] args) throws ParseException {
String input = "2010-12-10T20:03:53-06:00";
int colon = input.lastIndexOf(":");
input = input.substring(0, colon) + input.substring(colon + 1, input.length());
System.out.println(input);
DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = fmt.parse(input);
System.out.println("date = " + date);
}

Joda Time - different between timezones

I want to convert the current time to the time in a specific timezone with Joda time.
Is there a way to convert DateTime time = new DateTime() to a specific timezone, or perhaps to get the number of hours difference between time.getZone() and another DateTimeZone to then do time.minusHours or time.plusHours?
I want to convert the current time to the time in a specific timezone with Joda time.
It's not really clear whether you've already got the current time or not. If you've already got it, you can use withZone:
DateTime zoned = original.withZone(zone);
If you're just fetching the current time, use the appropriate constructor:
DateTime zoned = new DateTime(zone);
or use DateTime.now:
DateTime zoned = DateTime.now(zone);
Check out DateTimeZone & Interval:
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));
Interval:
Interval interval = new Interval(start, end); //start and end are two DateTimes
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
// ZonedDateTime.now() is same as ZonedDateTime.now(ZoneId.systemDefault()). In
// order to specify a specific timezone, use ZoneId.of(...) e.g.
// ZonedDateTime.now(ZoneId.of("Europe/London"));
ZonedDateTime zdtDefaultTz = ZonedDateTime.now();
System.out.println(zdtDefaultTz);
// Convert zdtDefaultTz to a ZonedDateTime in another timezone e.g.
// to ZoneId.of("America/New_York")
ZonedDateTime zdtNewYork = zdtDefaultTz.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zdtNewYork);
}
}
Output from a sample run:
2021-07-25T15:48:10.584414+01:00[Europe/London]
2021-07-25T10:48:10.584414-04:00[America/New_York]
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

How do you create a proper Epoch calendar object in Java?

I want to create a calendar object that is the epoch date. What's the 'correct' (if any) way to do it?
Date epochDate = new java.text.SimpleDateFormat ("dd/MM/yyyy HH:mm:ss z").parse("01/01/1970 01:00:00 GMT");
Calendar epochCal;
epochCal.setTime(epochDate);
// or maybe
Calendar epochCal;
epochCal.setTimeInMillis(1);
The 'setTimeInMillis()' method would work fine and be easily understood by others. It might also be clearer if you passed it 0 instead of 1. The first method has more line noise and just adds more chances that something can get screwed up in maintenance.
java.time
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Solution using the modern API:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.EPOCH;
System.out.println(instant);
}
}
Output:
1970-01-01T00:00:00Z
If at all you need an object referenced by java.util.Calendar, you can get the same using this object of Instant:
// If at all you need a Calendar object, derive it from instant
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(instant.toEpochMilli());
// Verification
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(calendar.getTime()));
Learn more about the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Calendar formatting issues

We're searching for information on how to format instances of java.util.Calendar and more general information and coding hints regarding transition from using java.util.Date to java.util.Calendar.
best,
phil
My hint would be not to use either Date or Calendar. Use Joda Time instead. It's much, much nicer than the built-in classes. JSR-310 will hopefully, eventually bring something Joda-like into the main library, but for the moment Joda is your best bet.
If you must stick to Date/Calendar, see java.text.DateFormat and java.text.SimpleDateFormat. Remember that they're not thread-safe though :(
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
If you are getting an object of java.util.Date from some API, your first step should be to convert it into Instant using Date#toInstant which can be converted to other types of modern Date-Time API.
A demo with the modern Date-Time API:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
System.out.println(instant);
ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc);
ZonedDateTime zdtNewYork = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtNewYork);
// Fixed offset
OffsetDateTime odtUtc = instant.atOffset(ZoneOffset.UTC);
System.out.println(odtUtc);
OffsetDateTime odtWithOffset0530Hours = instant.atOffset(ZoneOffset.of("+05:30"));
System.out.println(odtWithOffset0530Hours);
// OffsetDateTime from ZonedDateTime
OffsetDateTime odtNewYork = zdtNewYork.toOffsetDateTime();
System.out.println(odtNewYork);
// LocalDate in New York
LocalDate todayNewYork = zdtNewYork.toLocalDate();
System.out.println(todayNewYork);
// Alternatively
System.out.println(LocalDate.now(ZoneId.of("America/New_York")));
// LocalDateTime in New York
LocalDateTime nowNewYork = zdtNewYork.toLocalDateTime();
System.out.println(nowNewYork);
// Alternatively
System.out.println(LocalDateTime.now(ZoneId.of("America/New_York")));
// Formatted output
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
System.out.println(dtf.format(zdtNewYork));
}
}
Output:
2021-07-14T19:22:13.544911Z
2021-07-14T19:22:13.544911Z[Etc/UTC]
2021-07-14T15:22:13.544911-04:00[America/New_York]
2021-07-14T19:22:13.544911Z
2021-07-15T00:52:13.544911+05:30
2021-07-14T15:22:13.544911-04:00
2021-07-14
2021-07-14
2021-07-14T15:22:13.544911
2021-07-14T15:22:13.586971
Wed July 14 15:22:13 EDT 2021
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
Some helpful answers using java.time API:
Check this answer and this answer to learn how to use java.time API with JDBC.
How to use ParsePostion?
Timezone conversion.
SimpleDateFormat does not handle fraction-of-second beyond three digits in the millisecond part correctly.
How to convert LocalDate to ZonedDateTime?
'Z' is not the same as Z.
Day-of-month with ordinal.
The standard library does not support a formatted Date-Time object.
Never use SimpleDateFormat or DateTimeFormatter without a Locale.
How to check if timestamp (epoch time) is of today's or yesterday's?
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Parsing JavaScript Date string in Java

A JavaScript client sends some strings to my server, one of which comes in form of a JavaScript Date object's string representation.
Now, this JavaScript Date object has its own formatting and I was just wondering if there is a class that does the right conversion, as I am experiencing problems with the SimpleDateFormatter.
This is how a JavaScript Date string looks like: Tue Feb 12 2013 21:12:28 GMT+0100 (CET)
Best way to serialize the date in javascript is to use toUTCString (not just toString()); toUTCString will produce an rfc 822 date (in the same format as used by http). Then you can just use the following SimpleDateFormat pattern to parse it in java:
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
Personally I prefer the Joda Time formatters for one main reason: they're thread-safe and immutable, so you can create one, keep it statically, and reuse it without any worries. Joda also allows easy specification of time zones etc. Of course, they end up creating Joda objects, which is another advantage IMO - I try to steer clear of Java's date/time API wherever possible.
Having said that, we'd need to know more about the format you're trying to parse, and what's going wrong with SimpleDateFormatter. (As a general rule, if you're "experiencing problems" with something and want those problems fixed, it helps to describe what the problems are, ideally with a short but complete program to demonstrate the problem.)
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Tue Feb 12 2013 21:12:28 GMT+0100 (CET)";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d u H:m:s VVZ (z)", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
Output:
2013-02-12T21:12:28+01:00[Europe/Paris]
ONLINE DEMO
For any reason, if you need to convert this object of ZonedDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(zdt.toInstant());
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Categories