Extract Date from Zulu Time using Joda Time - java

I have a Zulu time "2011-08-12T20:17:46.384Z". How can i extract date part using java joda time?
I have read multiple question on Zulu Time but none answer my question.

Do you want the date in your own time zone or in Zulu (UTC)? Asking because it is never the same date in all time zones.
Date in Zulu time zone, the same date as in the string, is the easier requirement:
String zuluString = "2011-08-12T20:17:46.384Z";
DateTime dt = DateTime.parse(zuluString);
LocalDate datePart = dt.toLocalDate();
System.out.println(datePart);
Output:
2011-08-12
Getting the date in the default time zone of the JVM just requires a few chars more:
LocalDate datePart = dt.withZone(DateTimeZone.getDefault()).toLocalDate();
Output when run in Asia/Macau time zone:
2011-08-13
Which new API ?
Joda-Time is in maintenance mode and no longer recommended for new code. The Joda-Time home page says:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
java.time is built into Java since Java 8 and has also been backported to Java 6 and 7. You may start by following the second link below.
Links
Joda-Time - Home
Oracle tutorial: Date Time explaining how to use java.time.

I suggest you switch to the modern date-time API.
Using the modern java.time (JSR-310) API:
import java.time.LocalDate;
import java.time.OffsetDateTime;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = OffsetDateTime.parse("2011-08-12T20:17:46.384Z");
System.out.println(odt);
LocalDate date = odt.toLocalDate();
System.out.println(date);
}
}
Output:
2011-08-12T20:17:46.384Z
2011-08-12
Learn more about the modern date-time API at Trail: Date Time.
Check out the following lines from the home page of Joda-Time documentation:
Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).
Using the Joda-Time API:
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
public class Main {
public static void main(String[] args) {
DateTime dateTime = DateTime.parse("2011-08-12T20:17:46.384Z");
System.out.println(dateTime);
LocalDate date = dateTime.toLocalDate();
System.out.println(date);
}
}
Output:
2011-08-12T20:17:46.384Z
2011-08-12

Related

Convert LocalDate to TimeStamp with UTC

I am taking LocalDate as input and want to convert it into this format to search in oracle DB.
input - "2010-10-10"
Output- 10-OCT-10 07.39.02.713000000 AM UTC
I tried using TimeStamp and DateTime but getting date in these formats respectively.
2020-10-10 00:00:00.0
2020-10-10T00:00:00.000+05:30
I used
Timestamp.valueOf(startDate.atStartOfDay());
DateTime.parse(startDate.toString());
Can you please help me? Thank you in advance
Updated.
Parse the given string to LocalDate and convert it into ZonedDateTime using LocalDate#atStartOfDay(ZoneId).
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Testing {
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2010-10-10");
ZonedDateTime zdt = date.atStartOfDay(ZoneId.of("Etc/UTC"));
System.out.println(zdt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS a zzz", Locale.ENGLISH);
System.out.println(dtf.format(zdt));
}
}
Output:
2010-10-10T00:00Z[Etc/UTC]
2010-10-10 00:00:00.000 AM UTC
Learn more about java.time, 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.
Don't pass date and timestamp to oracle as strings (varchar2), just use bind variables of required data types: oracle.sql.DATE or oracle.sql.TIMESTAMP.
You can convert(cast) them in Oracle. Also you can change timezones using SYS_EXTRACT_UTC, TO_UTC_TIMESTAMP_TZ or AT TIME ZONE

Get only the date from the timestamp

This is my Below function in which I am passing timestamp, I need only the date in return from the timestamp not the Hours and Second. With the below code I am getting-
private String toDate(long timestamp) {
Date date = new Date (timestamp * 1000);
return DateFormat.getInstance().format(date).toString();
}
This is the output I am getting.
11/4/01 11:27 PM
But I need only the date like this
2001-11-04
Any suggestions?
Use SimpleDateFormat instead:
private String toDate(long timestamp) {
Date date = new Date(timestamp * 1000);
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
Updated: Java 8 solution:
private String toDate(long timestamp) {
LocalDate date = Instant.ofEpochMilli(timestamp * 1000).atZone(ZoneId.systemDefault()).toLocalDate();
return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
You can use this code to get the required results
protected Timestamp timestamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
protected String today_Date=timestamp.toString().split(" ")[0];
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:
You can use Instant#ofEpochSecond to get an Instant out of the given timestamp and then use LocalDate.ofInstant to get a LocalDate out of the obtained Instant.
Demo:
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(toDate(1636120105L));
}
static LocalDate toDate(long timestamp) {
return LocalDate.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
}
}
Output:
2021-11-05
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time. Check this answer and this answer to learn how to use java.time API with JDBC.
* 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. Note that Android 8.0 Oreo already provides support for java.time.
Joda-Time
The Joda-Time library offers a LocalDate class to represent a date-only value without any time-of-day nor time zone.
Time Zone
Determining a date requires a time zone. A moment just after midnight in Paris means a date that is a day ahead of the same simultaneous moment in Montréal. If you neglect to specify a time zone, the JVM’s current default time zone is applied – probably not what you want as results may vary.
Example Code
long millisecondsSinceUnixEpoch = ( yourNumberOfSecondsSinceUnixEpoch * 1000 ); // Convert seconds to milliseconds.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
LocalDate localDate = new LocalDate( millisecondsSinceUnixEpoch, timeZone );
String output = localDate.toString(); // Defaults to ISO 8601 standard format, YYYY-MM-DD.
Previous Day
To get the day before, as requested in a comment.
LocalDate dayBefore = localDate.minusDays( 1 );
Convert to j.u.Date
The java.util.Date & .Calendar classes should be avoided as they are notoriously troublesome. But if required, you may convert.
java.util.Date date = localDate.toDate(); // Time-of-day set to earliest valid for that date.

Time - hour minute manipulation

Is there an API to quickly manipulate (e.g. add, subtract) on time (hour, minute).
Pseudo code is listed below
Time t1 = "5 PM";
t1.add("5 minutes");
t1.subtract("90 minutes");
'course there is: http://download.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html#add%28int,%20int%29
You'll have to set the field parameter appropriately with one of the constants defined in the Field Summary section of the above page
java.time
The standard date-time library of Java SE 8 is rich with all such features.
Note: Quoted below is a notice at 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.
Given below is a demo of such features using java.time, the modern API:
import java.time.Duration;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalTime time = LocalTime.of(17, 30);
System.out.println(time);
time = time.plusMinutes(5);
System.out.println(time);
time = time.minusMinutes(90);
System.out.println(time);
// Parsing and formatting
DateTimeFormatter dtfInput = new DateTimeFormatterBuilder()
.appendPattern("h[:m[:s]] a") // Optional fields in square bracket
.parseCaseInsensitive() // Case-insensitive (AM/am/Am etc.)
.toFormatter(Locale.ENGLISH);
time = LocalTime.parse("5 PM", dtfInput);
System.out.println(time);
// Dealing with timezone?
ZonedDateTime zdt = ZonedDateTime.now().with(time);
System.out.println(zdt);
// Custom format
DateTimeFormatter timeAndZone12HourFormat = DateTimeFormatter.ofPattern("hh:mm:ss a'['VV']'");
DateTimeFormatter timeAndZone24HourFormat = DateTimeFormatter.ofPattern("HH:mm:ss'['VV']'");
System.out.println(zdt.format(timeAndZone12HourFormat));
System.out.println(zdt.format(timeAndZone24HourFormat));
// Adding/subtracting ISO 8601 Duration
Duration duration = Duration.parse("PT2H30M"); // 2 hours 30 minutes
zdt = zdt.plus(duration);
System.out.println(zdt.format(timeAndZone12HourFormat));
}
}
Output:
Learn more about java.time, 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.

Generating UTC Time in java

I want to get the UTC time for 01/01/2100 in Java to '2100-01-01 00:00:00'. I am getting "2100-01-01 00:08:00". Any idea, how to correct this.
public Date getFinalTime() {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
Date finalTime = null;
try
{
finalTime = df.parse("01/01/2100");
} catch (ParseException e)
{
e.printStackTrace();
}
calendar.setTime(finalTime);
return calendar.getTime();
}
You need to specify the time zone for the SimpleDateFormat as well - currently that's parsing midnight local time which is ending up as 8am UTC.
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(utc);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
df.setTimeZone(utc);
Date finalTime = null;
try
{
finalTime = df.parse("01/01/2100");
} catch (ParseException e)
{
e.printStackTrace();
}
calendar.setTime(finalTime);
As ever though, I would personally recommend using Joda Time which is far more capable in general. I'd be happy to translate your example into Joda Time if you want.
Additionally, I see you're returning calendar.getTime() - that's just the same as returning finalTime as soon as you've computed it.
Finally, just catching a ParseException and carrying on as if it didn't happen is a very bad idea. I'm hoping this is just sample code and it doesn't reflect your real method. Likewise I'm assuming that really you'll be parsing some other text - if you're not, then as Eyal said, you should just call methods on Calendar directly. (Or, again, use Joda Time.)
You need to set the time zone of the SimpleDateFormat object as well, otherwise it assumes the default time zone.
Anyway, it seems like using only a Calendar is enough in your case. Use its setters to set the right values for all fields (year, month, day, hour, etc), and then retrieve the 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 at 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 API:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDate = "01/01/2100";
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("d/M/u", Locale.ENGLISH);
ZonedDateTime zdt = LocalDate.parse(strDate, dtfInput)
.atStartOfDay(ZoneId.of("Etc/UTC"));
// Default format
System.out.println(zdt);
// Getting and displaying LocalDateTime
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
// A custom format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
// Alternatively dtfOutput.format(ldt);
String formatted = dtfOutput.format(zdt);
System.out.println(formatted);
// Converting to some other types
OffsetDateTime odt = zdt.toOffsetDateTime();
Instant instant = zdt.toInstant();
System.out.println(odt);
System.out.println(instant);
}
}
Output:
2100-01-01T00:00Z[Etc/UTC]
2100-01-01T00:00
2100-01-01 00:00:00
2100-01-01T00:00Z
2100-01-01T00:00:00Z
ONLINE DEMO
The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Note: The Date-Time without timezone name or timezone offset should be represented by LocalDateTime (which is used for events that are normally not represented with timezone information). In this sense, LocalDateTime is useless in this case and you should use ZonedDateTime itself or Instant or OffsetDateTime. I recommend you also check this answer and this answer if you are dealing with JDBC.
Learn more about java.time, 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.
java.time
Like Arvind Kumar Avinash I very clearly recommend that you use java.time, the modern Java date and time API, for your date and time work. If what you want is a fixed (constant) date and time, use OffsetDateTime.of().
OffsetDateTime finalTime = OffsetDateTime.of(2100, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
System.out.println(finalTime);
Output:
2100-01-01T00:00Z
The trailing Z means UTC.
Tutorial link
Oracle tutorial: Date Time explaining how to use java.time.
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(utc);
DateFormat dateformat = new SimpleDateFormat("dd/MM/yyyy");
dateformat.setTimeZone(utc);
Timezone needs to be set.

Output RFC 3339 Timestamp in Java

I want to output a timestamp with a PST offset (e.g., 2008-11-13T13:23:30-08:00). java.util.SimpleDateFormat does not seem to output timezone offsets in the hour:minute format, it excludes the colon. Is there a simple way to get that timestamp in Java?
// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp);
// prints "2008-11-13T12:23:30-0800" See the difference?
Also, SimpleDateFormat cannot properly parse the example above. It throws a ParseException.
// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")
Starting in Java 7, there's the X pattern string for ISO8601 time zone. For strings in the format you describe, use XXX. See the documentation.
Sample:
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
.format(new Date()));
Result:
2014-03-31T14:11:29+02:00
Check out the Joda Time package. They make RFC 3339 date formatting a lot easier.
Joda Example:
DateTime dt = new DateTime(2011,1,2,12,45,0,0, DateTimeZone.UTC);
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
String outRfc = fmt.print(dt);
From the "get it done dept," one solution is to use regexes to fix up the string after SimpleDateFormat has completed. Something like s/(\d{2})(\d{2})$/$1:$2/ in Perl.
If you are even remotely interested in this, I will edit this response with the working Java code.
But, yeah. I am hitting this problem too. RFC3339, I'm looking at you!
EDIT:
This works for me
// As a private class member
private SimpleDateFormat rfc3339 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String toRFC3339(Date d)
{
return rfc3339.format(d).replaceAll("(\\d\\d)(\\d\\d)$", "$1:$2");
}
I spent quite a lot of time looking for an answer to the same issue and I found something here : http://developer.android.com/reference/java/text/SimpleDateFormat.html
Suggested answer:
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZZZZZ").format(new Date());
If you notice I am using 5 'Z' instead of one. This gives the output with a colon in the offset like this: "2008-11-13T12:23:30-08:00". Hope it helps.
The problem is that Z produces the time zone offset without a colon (:) as the separator.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
Is not what exactly you need?
We can simply use ZonedDateTime class and DateTimeFormatter class for this.
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssxxx");
ZonedDateTime z2 = ZonedDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.SECONDS);
System.out.println("format =======> " + z2.format(format));
Output: format =======> 30-03-2020T05:57:37+00:00
I found a stray PasteBin that helped me out with the issue: http://pastebin.com/y3TCAikc
Just in case its contents later get deleted:
// I want 2008-11-13T12:23:30-08:00
String timestamp = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").format(new Date());
System.out.println(timestamp);
// prints "2008-11-13T12:23:30-0800" See the difference?
// Throws a ParseException
new SimpleDateFormat("yyyy-MM-dd'T'h:m:ssZ").parse("2008-11-13T13:23:30-08:00")
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'h:m:ss.SZ");
I made a InternetDateFormat class for RFC3339.
But source code comment is Japanese.
PS:I created English edition and refactoring a little.
i tried this format and worked for me yyyy-MM-dd'T'HH:mm:ss'Z'
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 largest city in the Pacific Time Zone is Los Angeles whose timezone name is America/Los_Angeles. Using ZoneId.of("America/Los_Angeles"), you can create an instance of ZonedDateTime which has been designed to adjust the timezone offset automatically on DST transitions.
If you need timezone offset but not the timezone name, you can convert a ZonedDateTime into OffsetDateTime using ZonedDateTime#toOffsetDateTime. Some other uses of OffsetDateTime are to create a Date-Time instance with a fixed timezone offset (e.g. Instant.now().atOffset(ZoneOffset.of("+05:30")), and to parse a Date-Time string with timezone offset.
Demo:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
ZoneId zoneIdLosAngeles = ZoneId.of("America/Los_Angeles");
ZonedDateTime zdtNowLosAngeles = ZonedDateTime.now(zoneIdLosAngeles);
System.out.println(zdtNowLosAngeles);
// With zone offset but without time zone name
OffsetDateTime odtNowLosAngeles = zdtNowLosAngeles.toOffsetDateTime();
System.out.println(odtNowLosAngeles);
// Truncated up to seconds
odtNowLosAngeles = odtNowLosAngeles.truncatedTo(ChronoUnit.SECONDS);
System.out.println(odtNowLosAngeles);
// ################ A winter date-time ################
ZonedDateTime zdtLosAngelesWinter = ZonedDateTime
.of(LocalDateTime.of(LocalDate.of(2021, 11, 20), LocalTime.of(10, 20)), zoneIdLosAngeles);
System.out.println(zdtLosAngelesWinter); // 2021-11-20T10:20-08:00[America/Los_Angeles]
System.out.println(zdtLosAngelesWinter.toOffsetDateTime()); // 2021-11-20T10:20-08:00
// ################ Parsing a date-time string with zone offset ################
String strDateTime = "2008-11-13T13:23:30-08:00";
OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
System.out.println(odt); // 2008-11-13T13:23:30-08:00
}
}
Output from a sample run:
2021-07-18T03:27:15.578028-07:00[America/Los_Angeles]
2021-07-18T03:27:15.578028-07:00
2021-07-18T03:27:15-07:00
2021-11-20T10:20-08:00[America/Los_Angeles]
2021-11-20T10:20-08:00
2008-11-13T13:23:30-08:00
ONLINE DEMO
You must have noticed that I have not used a DateTimeFormatter to parse the Date-Time string of your question. It is because your Date-Time string is compliant with ISO-8601 standards. 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.
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.
I tested a lot with this one, works well for me... In particular when it comes to parsing (and for formatting too), it is the closest I have found so far
DateTimeFormatter rfc3339Formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
DateTimeFormatter rfc3339Parser = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendValue(ChronoField.YEAR, 4)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.appendLiteral('T')
.appendValue(ChronoField.HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 2)
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 2, 9, true) //2nd parameter: 2 for JRE (8, 11 LTS), 1 for JRE (17 LTS)
.optionalEnd()
.appendOffset("+HH:MM","Z")
.toFormatter()
.withResolverStyle(ResolverStyle.STRICT)
.withChronology(IsoChronology.INSTANCE);
Test cases at https://github.com/guyplusplus/RFC3339-DateTimeFormatter

Categories