I need to convert joda time to Java time but having some issues
My joda time code :
p.s method is a long type (long argDateString)
DateTime istime = new DateTime(argDateString*1000);
DateTime NormalTime = istime.withZone(DateTimeZone.forID("UTC"));
return normalTime.toString();
My Java code :
Date istime = new date(argDateString*1000);
DateFormat normalTime = DateFormat.getDateTimeInstance(DateFormat.Full, DateFormat.Full);
Return normalTime.format(istime);
With Joda I was getting
1970-01-15T05:45:05.000Z
With Java I am getting
15 January 1970 05:45:05 o'clock UTC
So is there a way to get what i was getting with Joda time ?
Thanks
tl;dr
java.time.Instant
.ofEpochSecond(
Long.parseLong( input )
)
.toString()
Details
Never use Date and DateFormat classes. These are terribly flawed, and are now legacy. They were supplanted by the modern java.time classes defined in JSR 310. The java.time framework is the official successor to the Joda-Time project, both being led by the same man, Stephen Colebourne.
Your first bit of code makes no sense: argDateString*1000. Strings cannot be multiplied.
I suspect your text holds a number of seconds since the first moment of 1970 as seen in UTC. If so, use Long class to parse to a long primitive.
long seconds = Long.parseLong( input ) ; // Parse text into a number.
Pass that number to a static factory method for Instant.
Instant instant = Instant.ofEpochSecond( seconds ) ;
Now you have an object whose value represents a moment, a point on the timeline, as seen in UTC.
To generate text in your desired standard ISO 8601 format, merely call toString. The java.time classes use the ISO 8601 formats by default when generating/parsing text.
String output = instant.toString() ;
All this has been covered many times on Stack Overflow. Search to learn more.
I am trying to decode the date-time receiving from my APIs in my required format "yyyy-MM-dd"
I receive time in 2 format
1. "2022-05-05T11:32:12.542Z"
2. "2022-05-06T07:33:46.59928+00:00"
I am able to decode first format by parsing it using following pattern
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
but not able to understand the format for the 2nd condition.
Some more example example of 2nd Condition
"2022-05-06T06:30:25.583988+00:00"
"2022-05-05T11:32:49.393283+00:00"
P.S. I don't required parsing logic only needed the pattern
Full method used in the code for parsing 1st Condition
fun convertToFormat(src: String): String {
val originalFormat =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
val targetFormat = SimpleDateFormat("yyyy-MM-dd")
val date = originalFormat.parse(src)
return targetFormat.format(date)
}
tl;dr
If you only want to just pull the date portion of the input string, split.
"2022-05-05T11:32:12.542Z"
.split( "T" )
[ 0 ]
If you want to parse the input string, use OffsetDateTime & LocalDate.
OffsetDateTime
.parse(
input
)
.toLocalDate()
.toString() ;
Avoid legacy classes
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined by JSR 310. Never use SimpleDateFormat, Date, Calendar.
ISO 8601
Both of your exemple strings represent a moment as seen with an offset from UTC of zero hours-minutes-seconds.
Both of your example strings are in standard ISO 8601 format. The java.time classes support ISO 8601 formats by default when parsing/generating text. So no need to specify a formatting pattern.
Instant
Parse your input as objects of class Instant.
Instant instant1 = Instant.parse( "2022-05-05T11:32:12.542Z" ) ;
Instant instant2 = Instant.parse( "2022-05-06T07:33:46.59928+00:00" ) ;
See this code run live at IdeOne.com.
LocalDate
You want date only. So convert to the more flexible OffsetDateTime, and extract LocalDate.
LocalDate ld = Instant.atOffset( ZoneOffset.UTC ).toLocalDate() ;
Then call LocalDate#toString to generate text in ISO 8601 format YYYY-MM-DD.
Android
The java.time classes are built into Java 8 and later.
Android 26+ carries an implementation of java.time. For earlier Android, the latest tooling provides most of the functionality via “API desugaring”.
I was looking the SimpleDateFormat Docs, and found this reference: https://developer.android.com/reference/kotlin/java/text/SimpleDateFormat#examples
The pattern "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00, looks like very similar with this you are receiving (except about the seconds precision).
In my SQLite database, there is no Date datatype, so I have to store timestamps in text format.
Does the format yyyy-MM-dd HH:mm result in the correct ordering such that when you sort it lexicographically (by doing a normal sort ASC or DESC), it also orders by time value inherently?
Your format is the right idea; when sorted alphabetically it is also chronological.
You can take a step further, for a better version of that format, a standard format, to make your work simpler and easier.
ISO 8601
The ISO 8601 standard defines a variety of practical sensible formats for text representing date-time related values.
For a date and time combined the format is:
YYYY-MM-DDTHH:MM:SS.SZ
For example:
2016-04-28T18:22:20.123Z
This format as a string sorts chronologically as you need.
The T in the middle separates the Date portion from the Time portion. The Z on the end is short for Zulu which means UTC.
Generally, best practice is to convert your date-time values to UTC for storage and database. Your JDBC driver likely does that for you but I don't know about SQLite.
java.time
The java.time framework is built into Java 8 and later. Much of that functionality is back-ported to Java 6 & 7 in the ThreeTen-Backport project, and further adapted to Android in the ThreeTenABP project.
These new classes supplant the old java.util.Date/.Calendar and related classes that have proven to be poorly designed and troublesome.
These classes use ISO 8601 formats by default when parsing/generating textual representations of date-time values. Search Stack Overflow for many examples.
An Instant is a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
Simply call toString to generate a String representation of that value.
String stringForDatabase = instant.toString();
In Java 8 the current moment is captured to only milliseconds resolution due to legacy implementation of the Clock interface, for 3 decimal places for the fraction of a second. For example, 2016-04-29T00:12:57.123Z. In Java 9 and later has a modern implementation of Clock, able to capture the current moment in up to 9 decimal places (nanoseconds) as far as is supported by your computer’s hardware clock.
The default formatter used by Instant:toString prints the fraction of a second with 0, 3, 6, or 9 digits, as many as needed to represent the non-zero portion of the fraction of a second. All of these sort alphabetically & chronologically as requested, so you could store any of these in your database.
2016-04-29T00:12:57Z
2016-04-29T00:12:57.123Z
2016-04-29T00:12:57.123456Z
2016-04-29T00:12:57.123456789Z
These all parse directly back into an Instant instance. So no need to bother with defining your own formatting pattern as in the Question.
Instant instant = Instant.parse( "2016-04-29T00:12:57.123456789Z" );
To see the wall-clock time for a particular place, apply a time zone (ZoneId) to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Extract an Instant for storage back into the database.
Instant instant = zdt.toInstant();
String forDatabase = instant.toString();
Yes. Just that you should not miss any 0's in between.
('04' for April).
It's necessary to represent April as '04', not just '4'.
I have a String like this:
String timeString = "2230"
And I want to convert it into Time type.
I have tried to use this
def bookingTime = new Date().parse("2230")
But it doesn't work. Any ideas?
Thank you for the help!
Try (Groovy implementation):
String timeString = "2230"
def bookingTime = Date.parse("HHmm", timeString)
I do not know Groovy well, but I assume it does not have its own libraries, at least for date-time work. So this answer is aimed at Java libraries.
Date-Time versus Time-Of-Day
I want to convert it into Time type.
Apparently you want to represent only a time-of-day without any date or time zone.
The java.util.Date/.Calendar classes bundled with Java represent a combination of date and time-of-day. (By the way, these classes are notoriously troublesome, confusing, and flawed. Avoid them.)
So, Java 7 and earlier has no "Time" type. Java has had a java.sql.Time, but this class is a hack. A .Time is a j.u.Date with its date portion set to first day of 1970 UTC (the epoch). This class is only intended for use with databases and JDBC, and even then is supplanted by java.time (see below).
Instead you should use either:
Joda-Time library
java.time package (built into Java 8, inspired by Joda-Time, defined by JSR 310)
Both of these libraries offer a LocalTime class (Joda-Time, java.time) to represent a time-only value without date and without time zone.
Joda-Time
Some example code in Joda-Time 2.5, using Java syntax rather than Groovy.
If your input string had colons it would follow standard ISO 8601 format. The standard formats are used in both Joda-Time and java.time by default for parsing and generating strings.
LocalTime localTime = LocalTime.parse( "18:55" ); // ISO 8601 format used by default.
System.out.println( "localTime: " + localTime ); // localTime: 18:55:00.000
With your non-standard format, you must specify a formatter.
LocalTime localTime2 = DateTimeFormat.forPattern( "HHmm" ).parseLocalTime( "2230" );
System.out.println( "localTime2: " + localTime2 ); // localTime2: 22:30:00.000
I'm trying to parse the date returned as a value from the HTML5 datetime input field. Try it in Opera to see an example. The date returned looks like this: 2011-05-03T11:58:01Z.
I'd like to parse that into a Java Date or Calendar Object.
Ideally a solution should have the following things:
No external libraries (jars)
Handles all acceptable RFC 3339 formats
A String should be able to be easily validated to see if it is a valid RFC 3339 date
tl;dr
Instant.parse( "2011-05-03T11:58:01Z" )
ISO 8601
Actually, RFC 3339 is but a mere self-proclaimed “profile” of the actual standard, ISO 8601.
The RFC is different in that it purposely violates ISO 8601 to allow a negative offset of zero hours (-00:00) and gives that a semantic meaning of “offset unknown“. That semantic seems like a very bad idea to me. I advise sticking with the more sensible ISO 8601 rules. In ISO 8601, having no offset at all means the offset is unknown – an obvious meaning, whereas the RFC rule is abstruse.
The modern java.time classes use the ISO 8601 formats by default when parsing/generating strings.
Your input string represents a moment in UTC. The Z on the end is short for Zulu and means UTC.
Instant (not Date)
The modern class Instant represents a moment in UTC. This class replaces java.util.Date, and uses a finer resolution of nanoseconds rather than milliseconds.
Instant instant = Instant.parse( "2011-05-03T11:58:01Z" ) ;
ZonedDateTime (not Calendar)
To see that same moment through the wall-clock time used by the people of a certain region (a time zone), apply a ZoneId to get a ZonedDateTime. This class ZonedDateTime replaces the java.util.Calendar class.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
Converting
I strongly recommend avoiding the legacy date-time classes when possible. But if you must inter-operate with old code not yet updated to java.time, you may convert back-and-forth. Call new methods added to the old classes.
Instant replaces java.util.Date.
java.util.Date myJUDate = java.util.Date.from( instant ) ; // From modern to legacy.
Instant instant = myJUDate.toInstant() ; // From legacy to modern.
ZonedDateTime replaces GregorianCalendar.
java.util.GregorianCalendar myGregCal = java.util.GregorianCalendar.from( zdt ) ; // From modern to legacy.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // From legacy to modern.
If you have a java.util.Calendar that is actually a GregorianCalendar, cast.
java.util.GregorianCalendar myGregCal = ( java.util.GregorianCalendar ) myCal ; // Cast to the concrete class.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // From legacy to modern.
Bulleted concerns
Regarding your Question’s specific issues…
No external libraries (jars)
The java.time classes are built into Java 8, 9, 10, and later. An implementation is also included in later Android. For earlier Java and earlier Android, see the next section of this Answer.
Handles all acceptable RFC 3339 formats
The various java.time classes handle every ISO 8601 format I know of. They even handle some formats that mysteriously disappeared from later editions of the standard.
For other formats, see the parse and toString methods of the various classes such as LocalDate, OffsetDateTime, and so on. Also, search Stack Overflow as there are many examples and discussions on this topic.
A String should be able to be easily validated to see if it is a valid RFC 3339 date
To validate input strings, trap for DateTimeParseException.
try {
Instant instant = Instant.parse( "2011-05-03T11:58:01Z" ) ;
} catch ( DateTimeParseException e ) {
… handle invalid input
}
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, 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.
So, in principle this would be done using different SimpleDateFormat patterns.
Here a list of patterns for the individual declarations in RFC 3339:
date-fullyear: yyyy
date-month: MM
date-mday: dd
time-hour: HH
time -minute: mm
time-second: ss
time-secfrac: .SSS (S means millisecond, though - it is not clear what would happen if there are more or less than 3 digits of these.)
time-numoffset: (like +02:00 seems to be not supported - instead it supports the formats +0200, GMT+02:00 and some named time zones using z and Z.)
time-offset: 'Z' (not supporting other time zones) - you should use format.setTimezone(TimeZone.getTimeZone("UTC")) before using this.)
partial-time: HH:mm:ss or HH:mm:ss.SSS.
full-time: HH:mm:ss'Z' or HH:mm:ss.SSS'Z'.
full-date: yyyy-MM-dd
date-time: yyyy-MM-dd'T'HH:mm:ss'Z' or yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
As we can see, this seems not to be able to parse everything. Maybe it would be a better idea to implement an RFC3339DateFormat from scratch (using regular expressions, for simplicity, or parsing by hand, for efficiency).
Just found that google implemented Rfc3339 parser in Google HTTP Client Library
https://github.com/google/google-http-java-client/blob/dev/google-http-client/src/main/java/com/google/api/client/util/DateTime.java
Tested. It works well to parse varies sub seconds time fragment.
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.google.api.client.util.DateTime;
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.withZone(ZoneId.of("UTC"));
#Test
public void test1e9Parse() {
String timeStr = "2018-04-03T11:32:26.553955473Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.553Z");
}
#Test
public void test1e3Parse() {
String timeStr = "2018-04-03T11:32:26.553Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.553Z");
}
#Test
public void testEpochSecondsParse() {
String timeStr = "2018-04-03T11:32:26Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.000Z");
}
With the format you have e.g. 2011-05-03T11:58:01Z, below code will do. However, I recently tryout html5 datetime in Chrome and Opera, it give me 2011-05-03T11:58Z --> do not have the ss part which cannot be handled by code below.
new Timestamp(javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(date).toGregorianCalendar().getTimeInMillis());
Maybe not the most elegant way, but certainly working one I recently made:
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
cal.setTime(sdf.parse(dateInString.replace("Z", "").replace("T", "-")));
Though, The question is very old, but it may help one who wants it Kotlin version of this answer. By using this file, anyone can convert a Rfc3339 date to any date-format. Here I take a empty file name DateUtil and create a function called getDateString() which has 3 arguments.
1st argument : Your input date
2nd argument : Your input date pattern
3rd argument : Your wanted date pattern
DateUtil.kt
object DatePattern {
const val DAY_MONTH_YEAR = "dd-MM-yyyy"
const val RFC3339 = "yyyy-MM-dd'T'HH:mm:ss'Z'"
}
fun getDateString(date: String, inputDatePattern: String, outputDatePattern: String): String {
return try {
val inputFormat = SimpleDateFormat(inputDatePattern, getDefault())
val outputFormat = SimpleDateFormat(outputDatePattern, getDefault())
outputFormat.format(inputFormat.parse(date))
} catch (e: Exception) {
""
}
}
And now use this method in your activity/fuction/dataSourse Mapper to get Date in String format like this
getDate("2022-01-18T14:41:52Z", RFC3339, DAY_MONTH_YEAR)
and output will be like this
18-01-2022
For future reference, as an alternative, you could use ITU[1] which is hand-written to deal with exactly RFC-3339 parsing and also lets you easily deal with leap seconds. The library is dependency-free and only weighs in at 18 kB.
Full disclosure: I'm the author
try
{
final OffsetDateTime dateTime = ITU.parseDateTime(dateTimeStr);
}
catch (LeapSecondException exc)
{
// The following helper methods are available let you decide how to progress
//int exc.getSecondsInMinute()
//OffsetDateTime exc.getNearestDateTime()
//boolean exc.isVerifiedValidLeapYearMonth()
}
[1] - https://github.com/ethlo/itu
I'm using this:
DateTimeFormatter RFC_3339_DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
.append(ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendOffset("+HH:MM", "Z")
.optionalEnd()
.toFormatter();
Example:
String dateTimeString = "2007-05-01T15:43:26.3452+07:00";
ZonedDateTime zonedDateTime = ZonedDateTime.from(RFC_3339_DATE_TIME_FORMATTER.parse(dateTimeString));
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(datetimeInFRC3339format)