I am calling a rest web service that accepts Date. On client side, i have calling this service using JDK 8 OffsetDateTime Class.
Value that is going from my client side : 2018-07-01T05:30+05:30
Value that is accepted by Service : 2018-07-01T08:00:00.000+0000
Below is the code:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(ZoneId.of("UTC")));
cal.set(2018, 05, 31);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(cal.getTime().toInstant(), ZoneId.systemDefault());
Value of offsetDateTime that is coming with above code is 2018-07-01T05:30+05:30.
I am in IST time zone.
Can someone help as to what needs to be done to change date to 2018-07-01T08:00:00.000+0000.
tl;dr
If you want 8 AM on first day of July at UTC…
OffsetDateTime.of(
2018 , 7 , 1 , // Date (year, month 1-12 is Jan-Dec, day-of-month)
8 , 0 , 0 , 0 , // Time (hour, minute, second, nano)
ZoneOffset.UTC // Offset-from-UTC (0 = UTC)
) // Returns a `OffsetDateTime` object.
.format( // Generates a `String` object with text representing the value of the `OffsetDateTime` object.
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSZ" , Locale.US )
) // Returns a `String` object.
2018-07-01T08:00:00.000+0000
Avoid legacy date-time classes
Never use Calendar or Date classes. They were completely supplanted by the modern java.time classes such as OffsetDateTime. You are mixing the legacy classes with the modern, and that makes no sense.
java.time
Your Question is not clear about what are your inputs and what are your outputs versus your expectations.
If you goal is 8 AM on July 1 in UTC:
LocalDate ld = LocalDate.of( 2018 , Month.JULY , 1 ) ;
LocalTime lt = LocalTime.of( 8 , 0 ) ;
OffsetDateTime odt = OffsetDateTime.of( ld , lt , ZoneOffset.UTC ) ;
odt.toString(): 2018-07-01T08:00Z
That string format complies with ISO 8061 standard. If your destination refuses that input and accepts only 2018-07-01T08:00:00.000+0000, then we must defining a formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSZ" , Locale.US );
String output = odt.format( f );
2018-07-01T08:00:00.000+0000
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
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.
i think the below code will work
public static Date ConvertToGMT() {
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utc = new Date(dateFormat.format(date));
return utc;
}
You can do it like so,
offsetDateTime.atZoneSameInstant(ZoneId.of("Asia/Kolkata"))
Update
If you need an instance of OffsetDateTime here it is.
offsetDateTime.atZoneSameInstant(ZoneId.of("Asia/Kolkata")).toOffsetDateTime();
It’s not the answer you asked for, but it may be the answer you prefer in the end: Check once more whether the service you are calling accepts the format that you are already giving it. Both formats conform with ISO 8601, so it seems that the service accepts this standard format. If so, it should accept yours too.
In any case, use OffsetDateTime and the other classes from java.time exclusively and avoid the old and outdated Calendar and TimeZone classes. Basil Bourque’s answer shows the good solution.
Link: Wikipedia article: ISO 8601
Related
I am pulling data out of an Excel sheet, to load into Hubspot, using Java.
Here is how the data looks:
this date 2018-12-31 becomes Dec 31, 2017 once it's in side Hubspot.
This is wrong!
Here is my code:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date dt = null;
try {
dt = df.parse(member.getUsageEndDate());
} catch (java.text.ParseException e3) {
//dt = null;
e3.printStackTrace();
}
Long l = dt.getTime();
If I open the data in Notepad, it looks like this: 31-May-2018
How can I get this converted properly?
tl;dr
OffsetDateTime.of(
LocalDate.parse( "2018-12-31" ) ,
LocalTime.MIN ,
ZoneOffset.UTC
)
.toInstant()
.toEpochMilli()
1546214400000
Details
Avoid legacy date-time classes
You are using troublesome old date-time classes long ago made legacy by the arrival of the java.time classes built into Java 8 and later.
ISO 8601
Your input string happens to comply with the ISO 8601 standard formats. These formats are used by default in java.time when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( "2018-12-31" ) ;
First moment of the day
Apparently you need the first moment of the day in UTC for that date. Use OffsetDateTime with constant ZoneOffset.UTC.
OffsetDateTime odt = OffsetDateTime.of( ld , LocalTime.MIN , ZoneOffset.UTC ) ;
Dump to console.
System.out.println( "odt.toString(): " + odt );
See this code run live at IdeOne.com.
odt.toString(): 2018-12-31T00:00Z
Count-from-epoch
You appear to want the count of milliseconds since the epoch reference date of first moment of 1970 in UTC, 1970-01-01T00:00Z. Extract an Instant object, the basic building-block class in java.time, and call its handy Instant::toEpochMilli method.
long millisecondsSinceEpoch = odt.toInstant().toEpochMilli() ;
See this code run live at IdeOne.com.
1546214400000
Going the other direction.
Instant instant = Instant.ofEpochMilli( 1_546_214_400_000L ) ;
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.
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
I am trying to save a date in DB but i am getting the below error. I am confused because i am sending the same format but still throwing exception:
java.lang.IllegalArgumentException: Timestamp format must be
yyyy-mm-dd hh:mm:ss[.fffffffff]
If i am trying in SQL Developer in the below way it works fine
to_date('01/01/1900', 'mm/dd/yyyy')
Through java i tried doing as below
First Method
SimpleDateFormat format1 = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date myDate = format1.parse("01/01/1900 00:00:00");
Second Method
SimpleDateFormat format1 = new SimpleDateFormat("dd/MM/yyyy");
Date myDate = format1.parse("01/01/1900");
Where am i going wrong.
P.S : Please before marking it as duplicate and stopping people from answering question understand i have tried something and got the error.
tl;dr
myPreparedStatement.setObject(
… ,
LocalDate.parse(
"01/01/1900" ,
DateTimeFormatter.ofPattern( "dd/MM/uuuu" )
)
)
Details
The Answer by Just another Java programmer is correct.
Furthermore, you should not use strings to communicate date-time values with a database. Use date-time classes.
The modern way is with java.time classes, supplanting the troublesome legacy date-time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
You can parse directly from a string in standard ISO 8601 format.
LocalDate localDate = LocalDate.parse( "2016-01-23" );
Or specify each part.
LocalDate localDate = LocalDate.of( 2016, Month.JANUARY , 23 );
To parse other formats, use DateTimeFormatter class. Search Stack Overflow for many examples.
Database
If your JDBC driver complies with JDBC 4.2 or later, it should be able to pass a java.time type with PreparedStatement::setObject and fetch with ResultSet::getObject.
myPreparedStatement.setObject( … , localDate );
…or…
myPreparedStatement.setObject( … , localDate , JDBCType.DATE );
If your driver is not so enabled, fall back to using java.sql.Date. This awkward class pretends to represent a date-only value (but actually has a time component set to midnight which we are supposed to ignore). To convert to/from java.time look to new methods added to the old classes.
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );
And going the other direction.
LocalDate localDate = sqlDate.toLocalDate();
Pass to PreparedStatement::setDate.
myPreparedStatement.setDate( … , sqlDate );
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 java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and 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 SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
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.
Your date pattern does not match.
Better is to use a PreparedStatement so you never will rely on string conversion.
Hello I'm trying to convert a string in the format "17:50" to a date in android but when I try to run this code I get the correct hour from the string but the full date is from 1970. I need this date to schedule some local notifications on a given time of the day or in the next day.
String dtStart = "17:50";
SimpleDateFormat format = new SimpleDateFormat("H:mm");
try {
Calendar cal = Calendar.getInstance();
Date date = format.parse(dtStart);
cal.setTime(date);
System.out.println(cal.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
Thu Jan 01 17:50:00 BRT 1970
It's not an error, your code works well. Just if you want to get current date, you have to add the difference between current day and 1st of January 1970.
Your parsed date gives you 17:30 hours, which means 17 * 60 * 60 * 1000 ms + 30 * 60 + 1000 ms.
This way you can find current day: https://stackoverflow.com/a/1908419/4142087
What Anton suggested was correct, and the current day / next day logic is your custom implementation. You have to check current time and if it past that time, jump to setting up the alarm the next day.
java.time
You need a time-of-day class to represent your intended meaning. The legacy date-time classes from the earliest versions of Java lack such a class. The java.sql.Time class pretends to do this, but actually contains a date as well due to poor design decisions.
LocalTime
You want the LocalTime class for a time-of-day value without a date and without a time zone.
It uses a generic 24-hour single-day clock. Adding/subtracting spans of time wraps around the clock since it lacks any concept of dates.
Define a formatting pattern to match your input string.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "H:mm" ) ; // Uppercase `H` means 24-hour clock, lowercase `h` means 12-hour clock.
Parse input string.
String input = "7:50" ;
LocalTime lt = LocalTime.parse( input , f ) ;
Generate a string in standard ISO 8601 format.
String output = lt.toString() ;
07:50
Perhaps your business logic requires assigning the time-of-day to a date. To determine a moment, a point on the timeline, you must also specify a time zone.
LocalDate ld = LocalDate.of( 2018 , Month.MARCH , 27 ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
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.
I have a POST end-point that takes a couple of values, one being endDate and startDate. When the JSON posts in as:
{ "startDate" : "2015-01-30", "endDate" : "2015-12-30" }
Spring converts it to a java.util.Date Object that is always one day behind. In the logs I see:
Validating that startDate Thu Jan 29 16:00:00 PST 2015 < endDate Tue Dec 29 16:00:00 PST 2015
So it got the timezone correct. I had assumed it was related to UTC conversions, but I'm not sure how to configure this or modify it so that it converts it using the proper off-set. The timestamp portion of it isn't required - I only care that the year, day, and month match what is passed in.
if it matters, I'm using Spring (happened with 4.0.6 and 4.1.7) and a POST
tl;dr
LocalDate.parse( "2015-01-30" )
Use the right data type for the job
You are trying to fit a date-only value into a date-time type, java.util.Date. Square peg, round hole. While trying to come up with a time-of-day to associate with your date, a time zone is being injected, hence your problem.
LocalDate
Solution:
Never use the terrible old legacy date-time classes such as java.util.Date. Use only the modern java.time classes.
For a date-only value, use LocalDate.
Your input string happens to be in standard ISO 8601 format. The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern.
LocalDate ld = LocalDate.parse( "2015-01-30" ) ;
ZonedDateTime
If you want a moment, a date with a time-of-day, let java.time determine the first moment of the day. Never assume that moment is 00:00:00. In some zones on some dates it may be another time such as 01:00:00 because of anomalies such as Daylight Saving Time (DST).
ZonedId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // Let java.time determine the first moment of that date in that zone.
Instant
To adjust from to UTC (same moment, different wall-clock time), extract an Instant.
Instant instant = zdt.toInstant() ; // Adjust to UTC. Same moment, same simultaneous point on the timeline, different wall-clock time.
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.
String str="2015-01-30";
try{
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
isoFormat.setTimeZone(TimeZone.getTimeZone("PST"));
Date date = isoFormat.parse(str);
System.out.println(date);
}catch(ParseException e){
e.printStackTrace();
}
Check here http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-webdatabinder how to customize automatic Spring conversion:
#Controller
public class MyFormController {
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
// ...
}
I have created new SimpleDateFormat object which parses the given string as date object. The date format is as below:
SimpleDateFormat simpledateFormat = new SimpleDateFormat("dd-MM-yyyy");
And I am setting this date to calendar instance as below:
Date date = sampledateFormat.parse("01-08-2013");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
Now I am getting the day of the day of the week from this calendar. It is giving wrong value.
System.out.println(calendar.DAY_OF_WEEK);
The output it is giving is 7 i.e. Saturday but the expected value is 5 i.e. Thursday. Whats the problem?
You should print
calendar.get(Calendar.DAY_OF_WEEK);
The Calendar class has DAY_OF_WEEK as integer constant (with value 7) which should be used in conjunction with the Calendar.get(int) method. DAY_OF_WEEK is a calendar field, and all these constant fields are used to get() different values from the calendar instance. Their value is irrelevant.
tl;dr
LocalDate.parse( // Parse the input string by specified formatting pattern to get a date-only `LocalDate` object.
"01-08-2013" ,
DateTimeFormatter.ofPattern( "dd-MM-uuuu" )
)
.getDayOfWeek() // Get a `DayOfWeek` enum object. This is *not* a mere String.
.getValue() // Ask the `DayOfWeek` object for its number, 1-7 for Monday-Sunday per ISO 8601 standard.
4
java.time
The modern approach uses the java.time classes that supplanted the troublesome old legacy date-time classes such as SimpleDateFormat and Date and Calendar.
The LocalDate class represents a date-only value without time-of-day and without time zone.
Define a formatting pattern to match.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ;
Parse the input string.
LocalDate ld = LocalDate.parse( "01-08-2013" , f ) ;
ld.toString(): 2013-08-01
Interrogate for the day-of-week. Get a DayOfWeek enum object, one of seven pre-defined objects, for Monday-Sunday.
DayOfWeek dow = ld.getDayOfWeek() ;
dow.toString(): THURSDAY
You can ask that DayOfWeek object for a localized name and for a number 1-7 for Monday-Sunday per the ISO 8601 standard.
int dowNumber = dow.getValue() ;
4
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Or Locale.US, Locale.ITALY, etc.
jeudi
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, 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.