I want to convert the timestamps which are in different formats to one format
I want to convert following timestamps to single format
Time Stamp 1 : 2022-08-17T18:28:07.288496+05:30
Time Stamp 2 : 2022-10-27T13:17:47.987736542Z
to
yyyy-MM-dd'T'HH:mm:ss format
I have tried using DateFormatter of Java but it gives ParseException. Also used SimpleDateFormatter but was getting same exceptions.
Please suggest package or methods for the same.
Edit : Code I used for conversion
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(timestamp, formatter);
System.out.println(localDateTime);
Using java.time here is a good idea compared to java.util.Date, Calendar and so on, but you have to use specific classes that match the information inside a String that represents a datetime or timestamp.
In your case, the String contains the following information:
year
month of year
day of month
hour of day
minute of hour
second of minute
fractions of second
offset from UTC
In particular, it's the last one (offset from UTC) which makes your attempt fail because you (1) don't consider it in the pattern of the DateTimeFormatter and (2) you use a class that cannot store it (LocalDateTime is not able / designed to hold information about a zone or an offset.
Having Strings with an offset can be stored in / parsed to OffsetDateTimes, if they are ISO formatted (as your examples are), you don't even need to apply a custom DateTimeFormatter. You can simply call OffsetDateTime.parse(String).
You can then define a desired format for an output by creating a custom DateTimeFormatter and apply it in OffsetDateTime.format(DateTimeFormatter).
Here's an example:
public static void main(String[] args) {
// example Strings (your ones)
String timestampOne = "2022-08-17T18:28:07.288496+05:30";
String timestampTwo = "2022-10-27T13:17:47.987736542Z";
// directly parse them to get instances of OffsetDateTime
OffsetDateTime odtOne = OffsetDateTime.parse(timestampOne);
OffsetDateTime odtTwo = OffsetDateTime.parse(timestampTwo);
// prepare a formatter for your desired output
DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss");
// and print the values of the OffsetDateTimes formatted by that DateTimeFormatter
System.out.println(odtOne.format(dtfOut));
System.out.println(odtTwo.format(dtfOut));
}
Output:
2022-08-17T18:28:07
2022-10-27T13:17:47
This question already has answers here:
How to set time zone of a java.util.Date?
(12 answers)
Closed 2 years ago.
I have a java.util.Date object. When I format it to String using:
String timeString = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss-Z").format(time);
I get:
2020-03-26-14:40:55-+0200
So, I somehow have the correct time zone (but I can have any time zone, not only +2), this is good.
I want to convert this date to UTC, and then convert it to String. If I send an object with a date to the client, then Jackson will automatically convert it to UTC. But I want to do this manually.
How can I do this?
It is not recommended anymore to use java.util for date-time operations, especially not for time-zone or offset conversions...
Instead, use java.time:
public static void main(String[] args) {
// the String (with a strange formatting) to be parsed
String datetime = "2020-03-26-14:40:55-+0200";
// parse it to an OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(datetime,
// using a formatter for this specific pattern
DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-x"));
// print the parsing result
System.out.println(odt);
// then convert it to UTC (keeping the moment & adjusting the offset)
OffsetDateTime odtUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
// print the conversion result
System.out.println(odtUtc);
}
gives you the following output
2020-03-26T14:40:55+02:00
2020-03-26T12:40:55Z
java.time
I understand that you have got a field of type java.util.Date that you cannot afford to change just now. For any operation on that Date you should still convert it to a modern Instant first and then do your further work from there. For converting it to a string in UTC you may use the very simple:
String timeString = yourJavaUtilDate.toInstant().toString();
System.out.println(timeString);
Example output:
2020-03-26T12:40:55Z
While an Instant is a point in time without time zone or offset, just like a Date is, Instant.toString() produces a string in UTC in ISO 8601 format, which I find quite nice. If you wanted the peculiar format mentioned in your question (you must have very special reasons for that):
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd-HH:mm:ss-Z");
String timeString = yourJavaUtilDate.toInstant()
.atOffset(ZoneOffset.UTC)
.format(formatter);
2020-03-26-12:40:55-+0000
Your format pattern string from SimpleDateFormat works with the modern DateTimeFormatter too. That is not always the case, there are differences between the sets of format pattern letters for the two, only many of the letters have the same or similar meaning.
I am myself working with a very old code base that over the years has acquired a messy mixture of outdated and modern date and time classes. So we’re constantly converting back and forth between Date, LocalDate, OffsetDateTime, XMLGregorianCalendar and many other classes, which is far from ideal, and it will take some years still to get to the sweet spot where we will be using the modern classes only.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
By means of classes like SimpleDateFormat it is possible to format time and date in a suitable format.
Examples here
https://developer.android.com/reference/java/text/SimpleDateFormat#examples
In Java it starts with milliseconds value and then that value gets translated into human readable format.
Sometime it is useful to have that value instead of the human readable form.
Example:
If I am not wrong the 1578738100000 value just means the UTC value Sat Jan 11 2020 10:21:40.
Is it possible to have a format string that yields a string with milliseconds instead of the human readable form?
I know that it is possible to get the milliseconds value directly from the Date class but what I am asking here is whether milliseconds are one of the possible format string to feed SimpleDateFormat (or similar classes) with.
Be clear in understanding that date-time value objects and formatter objects play different roles.
A date-time object has no format, it represents a date and/or time-of-day with or without the context of a time zone or offset-from-UTC.
A formatter has no value, no date nor time-of-day. A formatter’s job is to work with a date-time object to produce text in a certain format representing that date-time object’s value.
So tracking a count of milliseconds since the epoch reference is the job of the date-time object, not the formatter. Producing human-readable text is the job of the formatter. So, no, the formatter does not produce a count of milliseconds.
And, no, you should not be using a count of milliseconds to communicate date-time values. Such numbers have no meaning to a human reader which leads to easily missing erroneous data. And such data does not readily identify itself - is it a number of whole seconds, milliseconds, microseconds, or nanoseconds? And what is the epoch reference date, which of the couple dozen commonly used epochs?
Instead communicate date-time values as text using the ISO 8601 standard formats.
Another problem: you are using terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
If your number is a count of milliseconds since the epoch reference of first moment of 1970 in UTC, parse as a Instant.
Instant instant = Instant.ofEpochMilli( 1_578_738_100_000L ) ;
If you insist on working with a count-from-epoch against my advice, you can interrogate the Instant.
long milliseconds = instant.toEpochMilli() ;
Generate text in standard ISO 8601 format.
String output = instant.toString() ;
For other formats, adjust the Instant into an OffsetDateTime or ZonedDateTime object, and generate text with a DateTimeFormatter. All this has been covered many many times already. So search Stack Overflow to learn more.
instant
.atZone(
ZoneId.of( "America/Montreal" )
)
.format(
DateTimeFormatter
.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
)
Lastly, be aware that while the legacy classes were limited to a resolution of milliseconds, the java.time classes revolve to the much finer nanoseconds. So beware of possible data loss when calling Instant::toEpochMilli as any microseconds or nanoseconds are ignored,
The old and outdated SimpleDateFormat class cannot do that. Its replacement, the modern DateTimeFormatter, can.
DateTimeFormatter epochMilliFormatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.INSTANT_SECONDS)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
Instant sampleInstant = OffsetDateTime
.of(2020, 1, 11, 10, 21, 40, 0, ZoneOffset.UTC)
.toInstant();
String formattedValue = epochMilliFormatter.format(sampleInstant);
System.out.println(formattedValue);
Output from this snippet is the number you mentioned:
1578738100000
Using ChronoField.INSTANT_SECONDS in the formatter gives us the seconds since the epoch. We wanted milliseconds, so we need to append ChronoField.MILLI_OF_SECOND immediately and make sure that they are printed in exact 3 positions, zero padded. This is what the 3 as 2nd argument to appendValue() does.
Is it possible to have a format string that yields a string with
milliseconds …?
No, with a format pattern string it is not possible, neither with SimpleDateFormat nor with DateTimeFormatter. You can go through the possible pattern letter of each and see that there is no pattern letter for neither seconds nor milliseconds since the epoch.
Are you sure that you want it, though? Even if this is for storing or for data interchange between systems, using milliseoncds since the epoch is not generally recommended exactly because they not human readable and therefore troublesome in debugging and in ad hoc queries. For most purposes you will be better off using a string in ISO 8601 format, like 2020-01-11T10:21:40Z. See the other answer by Basil Bourque for details. ISO 8601 format has been designed to be readable by both humans and computers.
You should not have wanted to use SimpleDateFormat anyway
The SimpleDateFormat class is notoriously troublesome (though even more for parsing than for formatting). It is also long outdated. The Date class that you mentioned is poorly designed and long outdated too. I recommend that you use java.time, the modern Java date and time API, as I do above.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of DateTimeFormatter with the format pattern letters that it accepts.
Wikipedia article: ISO 8601
This question already has answers here:
Parsing ISO-8601 DateTime with offset with colon in Java
(4 answers)
String date into Epoch time
(4 answers)
Closed 3 years ago.
I have this format:
2011-10-10T01:45:20+00:00
I tried using LocalDateTime.parse("2011-10-10T01:45:20+00:00")
but I got error:
java.time.format.DateTimeParseEception: Text '2011-10-10T01:45:20+00:00' could not be parse, unparsed text found
The default formatter is DateTimeFormatter.ISO_LOCAL_DATE_TIME : '2011-12-03T10:15:30', the offset is not in,
You may parse using OffsetDateTime class that uses DateTimeFormatter.ISO_OFFSET_DATE_TIME : '2011-12-03T10:15:30+01:00' as formatter
OffsetDateTime.parse("2011-10-10T01:45:20+00:00") // print 2011-10-10T01:45:20Z
You can still use LocalDateTime but you need to specify the formatter
LocalDateTime.parse("2011-10-10T01:45:20+00:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 2011-10-10T01:45:20
Oracle Documentation
tl;dr
OffsetDateTime.parse( "2011-10-10T01:45:20+00:00" )
Wrong class
The LocalDateTime class is not appropriate to your input. That class represents only a date and a time-of-day but without any offset-from-UTC or time zone, so it does not represent a moment, is not a point on the timeline.
Your input string in contrast represents a moment, with an offset-from-UTC of zero hours-minutes-seconds: +00:00
OffsetDateTime
Correct class for your input is OffsetDateTime.
Your input string is in standard ISO 8601 format. These standard formats are used by default in the java.time classes. So no need to specify a formatting pattern.
OffsetDateTime odt = OffsetDateTime.parse( "2011-10-10T01:45:20+00:00" ) ;
See this code run live at IdeOne.com.
odt.toString(): 2011-10-10T01:45:20Z
FYI, the difference between offset and zone:
An offset-from-UTC is merely a number of hours-minutes-seconds. Nothing more. Represented by ZoneOffset class.
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. A time zone carries a name in Continent/Region format such as America/Montreal or Africa/Tunis. Represented by ZoneId class.
You could provide ISO date formatter in the parse method like this
import java.time.format.DateTimeFormatter
LocalDate.parse("2011-10-10T01:45:20+00:00", DateTimeFormatter.ISO_DATE_TIME)
I am using following code to get date in "dd/MM/yyyy HH:mm:ss.SS" format.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: "+strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
System.out.println("Current date in Date Format: "+date);
}
}
and am getting following output
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: Thu Jan 05 21:10:17 IST 2012
Kindly suggest what i should do to display the date in same string format(dd/MM/yyyy HH:mm:ss.SS) i.e i want following output:
Current date in String Format: 05/01/2012 21:10:17.287
Current date in Date Format: 05/01/2012 21:10:17.287
Kindly suggest
SimpleDateFormat
sdf=new SimpleDateFormat("dd/MM/YYYY hh:mm:ss");
String dateString=sdf.format(date);
It will give the output 28/09/2013 09:57:19 as you expected.
For complete program click here
You can't - because you're calling Date.toString() which will always include the system time zone if that's in the default date format for the default locale. The Date value itself has no concept of a format. If you want to format it in a particular way, use SimpleDateFormat.format()... using Date.toString() is almost always a bad idea.
The following code gives expected output. Is that what you want?
import java.util.Calendar;
import java.util.Date;
public class DateAndTime {
public static void main(String[] args) throws Exception {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS");
String strDate = sdf.format(cal.getTime());
System.out.println("Current date in String Format: " + strDate);
SimpleDateFormat sdf1 = new SimpleDateFormat();
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
String string = sdf1.format(date);
System.out.println("Current date in Date Format: " + string);
}
}
Use:
System.out.println("Current date in Date Format: " + sdf.format(date));
tl;dr
Use modern java.time classes.
Never use Date/Calendar/SimpleDateFormat classes.
Example:
ZonedDateTime // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone).
.now( // Capture the current moment.
ZoneId.of( "Africa/Tunis" ) // Always specify time zone using proper `Continent/Region` format. Never use 3-4 letter pseudo-zones such as EST, PDT, IST, etc.
)
.truncatedTo( // Lop off finer part of this value.
ChronoUnit.MILLIS // Specify level of truncation via `ChronoUnit` enum object.
) // Returns another separate `ZonedDateTime` object, per immutable objects pattern, rather than alter (“mutate”) the original.
.format( // Generate a `String` object with text representing the value of our `ZonedDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // This standard ISO 8601 format is close to your desired output.
) // Returns a `String`.
.replace( "T" , " " ) // Replace `T` in middle with a SPACE.
java.time
The modern approach uses java.time classes that years ago supplanted the terrible old date-time classes such as Calendar & SimpleDateFormat.
want current date and time
Capture the current moment in UTC using Instant.
Instant instant = Instant.now() ;
To view that same moment through the lens of the wall-clock time used by the people of a particular region (a time zone), 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( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Or, as a shortcut, pass a ZoneId to the ZonedDateTime.now method.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" ) ) ;
The java.time classes use a resolution of nanoseconds. That means up to nine digits of a decimal fraction of a second. If you want only three, milliseconds, truncate. Pass your desired limit as a ChronoUnit enum object.
ZonedDateTime
.now(
ZoneId.of( "Pacific/Auckland" )
)
.truncatedTo(
ChronoUnit.MILLIS
)
in “dd/MM/yyyy HH:mm:ss.SS” format
I recommend always including the offset-from-UTC or time zone when generating a string, to avoid ambiguity and misunderstanding.
But if you insist, you can specify a specific format when generating a string to represent your date-time value. A built-in pre-defined formatter nearly meets your desired format, but for a T where you want a SPACE.
String output =
zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )
;
sdf1.applyPattern("dd/MM/yyyy HH:mm:ss.SS");
Date date = sdf1.parse(strDate);
Never exchange date-time values using text intended for presentation to humans.
Instead, use the standard formats defined for this very purpose, found in ISO 8601.
The java.time use these ISO 8601 formats by default when parsing/generating strings.
Always include an indicator of the offset-from-UTC or time zone when exchanging a specific moment. So your desired format discussed above is to be avoided for data-exchange. Furthermore, generally best to exchange a moment as UTC. This means an Instant in java.time. You can exchange a Instant from a ZonedDateTime, effectively adjusting from a time zone to UTC for the same moment, same point on the timeline, but a different wall-clock time.
Instant instant = zdt.toInstant() ;
String exchangeThisString = instant.toString() ;
2018-01-23T01:23:45.123456789Z
This ISO 8601 format uses a Z on the end to represent UTC, pronounced “Zulu”.
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.
Here's a simple snippet working in Java 8 and using the "new" date and time API LocalDateTime:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss.SS");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
The output in your first printline is using your formatter. The output in your second (the date created from your parsed string) is output using Date#toString which formats according to its own rules. That is, you're not using a formatter.
The rules are as per what you're seeing and described here:
http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#toString()
Disclaimer: this answer does not endorse the use of the Date class (in fact it’s long outdated and poorly designed, so I’d rather discourage it completely). I try to answer a regularly recurring question about date and time objects with a format. For this purpose I am using the Date class as example. Other classes are treated at the end.
You don’t want to
You don’t want a Date with a specific format. Good practice in all but the simplest throw-away programs is to keep your user interface apart from your model and your business logic. The value of the Date object belongs in your model, so keep your Date there and never let the user see it directly. When you adhere to this, it will never matter which format the Date has got. Whenever the user should see the date, format it into a String and show the string to the user. Similarly if you need a specific format for persistence or exchange with another system, format the Date into a string for that purpose. If the user needs to enter a date and/or time, either accept a string or use a date picker or time picker.
Special case: storing into an SQL database. It may appear that your database requires a specific format. Not so. Use yourPreparedStatement.setObject(yourParamIndex, yourDateOrTimeObject) where yourDateOrTimeObject is a LocalDate, Instant, LocalDateTime or an instance of an appropriate date-time class from java.time. And again don’t worry about the format of that object. Search for more details.
You cannot
A Date hasn’t got, as in cannot have a format. It’s a point in time, nothing more, nothing less. A container of a value. In your code sdf1.parse converts your string into a Date object, that is, into a point in time. It doesn’t keep the string nor the format that was in the string.
To finish the story, let’s look at the next line from your code too:
System.out.println("Current date in Date Format: "+date);
In order to perform the string concatenation required by the + sign Java needs to convert your Date into a String first. It does this by calling the toString method of your Date object. Date.toString always produces a string like Thu Jan 05 21:10:17 IST 2012. There is no way you could change that (except in a subclass of Date, but you don’t want that). Then the generated string is concatenated with the string literal to produce the string printed by System.out.println.
In short “format” applies only to the string representations of dates, not to the dates themselves.
Isn’t it strange that a Date hasn’t got a format?
I think what I’ve written is quite as we should expect. It’s similar to other types. Think of an int. The same int may be formatted into strings like 53,551, 53.551 (with a dot as thousands separator), 00053551, +53 551 or even 0x0000_D12F. All of this formatting produces strings, while the int just stays the same and doesn’t change its format. With a Date object it’s exactly the same: you can format it into many different strings, but the Date itself always stays the same.
Can I then have a LocalDate, a ZonedDateTime, a Calendar, a GregorianCalendar, an XMLGregorianCalendar, a java.sql.Date, Time or Timestamp in the format of my choice?
No, you cannot, and for the same reasons as above. None of the mentioned classes, in fact no date or time class I have ever met, can have a format. You can have your desired format only in a String outside your date-time object.
Links
Model–view–controller on Wikipedia
All about java.util.Date on Jon Skeet’s coding blog
Answers by Basil Bourque and Pitto explaining what to do instead (also using classes that are more modern and far more programmer friendly than Date)
If you are using JAVA8 API then this code will help.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeString = LocalDateTime.now().format(formatter);
System.out.println(dateTimeString);
It will print the date in the given format.
But if you again create a object of LocalDateTime it will print the 'T' in between the date and time.
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime.toString());
So as mentioned in earlier posts as well, the representation and usage is different.
Its better to use "yyyy-MM-dd'T'HH:mm:ss" pattern and convert the string/date object accordingly.
use
Date date = new Date();
String strDate = sdf.format(date);
intead Of
Calendar cal = Calendar.getInstance();
String strDate = sdf.format(cal.getTime());
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateAndTime{
public static void main(String[] args)throws Exception{
Date date = new Date(System.currentTimeMillis());
DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SS",
Locale.ENGLISH);
String strDate = format.format(date);
System.out.println("Current date in String Format: "+strDate);
}
}
use this code u will get current date in expected string format