Problem adding minutes with plusMinutes - java

I'm trying to add some minutes to a date using plusMinutes, but it just doesn't add anything at all:
Here's the code:
String currentDate ;
SimpleDateFormat myFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date1= null;
DateTime dt;
currentDate ="27/12/2010 11:29" ;
try {
date1= myFormat.parse(currentDate);
} catch (ParseException ex) {
ex.printStackTrace();
}
dt = new DateTime(date1);
dt.plusMinutes(30);

Javadoc says
Returns a copy of this datetime plus the specified number of millis.
so
do something like
dt = new DateTime(date1);
dt = dt.plusMinutes(30);
System.out.println(""+dt);

Beauty of joda is that most of their classes are immutable like String in Java. Update operations doesn't change the original object. So plusMinutes(...) returns a new copy of the DateTime with the minutes added which you can assign to a new variable as shown below.
DateTime newDt=dt.plusMinites(30);
System.out.println(newDt);

I think you want dt = dt.plusMinutes(30);
plusMinutes returns a calculated dateTime. It does not modify the dateTime it is called on.

tl;dr
java.time.LocalDateTime.parse(
"27/12/2010 11:29" ,
DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm" )
).plusMinutes( 30 )
2010-12-27T11:59
Tip: If you intended this to be a moment, a specific point on the timeline, apply the context of a time zone (ZoneId) to get a ZonedDateTime.
java.time
Your Question uses the troublesome old date-time classes from the earliest versions of Java, and your Question uses the Joda-Time project which is now in maintenance mode. Both have been supplanted by the java.time classes built into Java 8 and later.
Your string input lacks an indicator of time zone or offset-from-UTC. So parse as a java.time.LocalDateTime.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm" ) ;
LocalDateTime ldt = LocalDateTime.parse( "27/12/2010 11:29" , f ) ;
ldt.toString(): 2010-12-27T11:29
Note that you do not have an actual moment, this is not a specific point on the timeline. This is only a vague idea about potential moments along a range of about 26-27 hours. To determine an actual moment, place this in the context of a time zone (or offset): ZonedDateTime zdt = ldt.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;.
Add your minutes.
LocalDateTime later = ldt.plusMinutes( 30 ) ;
later.toString(): 2010-12-27T11:59
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.

Related

Why aren't milliseconds excluded from JSON when using dateFormat in Jackson's ObjectMapper with Java 8 dates?

I am trying to figure out why Jackson (2.9.5) formats dates from Java 8 incorrectly.
data class Test(
val zonedDateTim: ZonedDateTime = ZonedDateTime.now(),
val offsetDateTim: OffsetDateTime = OffsetDateTime.now(),
val date: Date = Date(),
val localDateTime: LocalDateTime = LocalDateTime.now()
)
val mapper = ObjectMapper().apply {
registerModule(KotlinModule())
registerModule(JavaTimeModule())
dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
enable(SerializationFeature.INDENT_OUTPUT)
}
println(mapper.writeValueAsString(Test()))
From the date format I provided I would expect to get dates formatted without milliseconds but instead the result looks like this:
{
"zonedDateTim" : "2018-07-27T13:18:26.452+02:00",
"offsetDateTim" : "2018-07-27T13:18:26.452+02:00",
"date" : "2018-07-27T13:18:26",
"localDateTime" : "2018-07-27T13:18:26.452"
}
Why are milliseconds being included in the formatted dates?
dateFormat only applies to Date objects - the 3 other objects are handled by the JavaTimeModule, which uses ISO formatting by default.
If you want a different format, you can use:
val format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
val javaTimeModule = JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, LocalDateTimeSerializer(format));
javaTimeModule.addSerializer(ZonedDateTime.class, ZonedDateTimeSerializer(format));
mapper.registerModule(javaTimeModule);
You may also need to add mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); but I'm not 100% sure that it's necessary.
Also note that with that format, you will lose time zone and offset information. So you may want a different format for Offset/Zoned-DateTimes.
The Answer by assylias is correct. Here are some further thoughts.
Truncate
If you really do not want the fractional second at all, truncate to whole seconds.
Instant instant = Instant.now().truncatedTo( ChronoUnit.SECONDS ) ;
OffsetDateTime odt = OffsetDateTime.now().truncatedTo( ChronoUnit.SECONDS ) ;
ZonedDateTime zdt = ZonedDateTime.now().truncatedTo( ChronoUnit.SECONDS ) ;
The formatters used by the various toString methods by default omit any text representing the fractional second if the value is zero.
So the value of:
2018-07-27T13:18:26.452+02:00
…becomes:
2018-07-27T13:18:26.000+02:00
…and its String representation will be generated as seconds without a fraction:
2018-07-27T13:18:26+02:00
Try it.
OffsetDateTime odt = OffsetDateTime.parse( "2018-07-27T13:18:26.452+02:00" ) ;
OffsetDateTime odtTrunc = odt.truncatedTo( ChronoUnit.SECONDS ) ;
System.out.println( "odt.toString(): " + odt ) ;
System.out.println( "odtTrunc.toString(): " + odtTrunc ) ;
Try that code live at IdeOne.com.
odt.toString(): 2018-07-27T13:18:26.452+02:00
odtTrunc.toString(): 2018-07-27T13:18:26+02:00
Avoid legacy classes
The code in your Question confuses me. Do not mix the troublesome old legacy date-time classes such as Date & SimpleDateFormat with the modern java.time classes. The legacy classes are entirely supplanted by the modern ones.
Timeline
Be clear that LocalDateTime serves a very different purpose than Instant, OffsetDateTime, and ZonedDateTime. A LocalDateTime object purposely lacks any concept of time zone or offset-from-UTC. So it cannot represent a moment, is not a point on the timeline.
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, 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.

Unmarshalling JSON sql Date fields from servlet, mine gets date wrong?

I am using JSON to get data from an HttpServlet for data object class definitions that are shared between the servlet and a java client. If I print out the response from the api call I can see that the instance variable is correct. Then when I map it using Jackson object mapper and look at the instance the value is wrong, always by one day lower then the date in the response and in the database.
The response looks like:
[{"coveragePK":3,"agentPK":2,"serviceCoveragePK":12,
"coverageDate":"2018-02-27","duration":10,"remainder":1,
"startTime":"07:30:00","query":""},
{"coveragePK":4,"agentPK":2,"serviceCoveragePK":13,
"coverageDate":"2018-02-27","duration":8,"remainder":2,
"startTime":"10:00:00","query":""}]
and after I map it I get:
Date: 2018-02-26 which is printed with
java.sql.Date date = coverages[i].getCoverageDate();
System.out.println("Date: " + date.toString());
If I convert the sql.Date to a LocalDate the result is the same as one would expect.
I use the following to write the json where coverages is an ArrayList.
ObjectMapper mapper = new ObjectMapper();
String psWindows = mapper.writeValueAsString(coverages);
PrintWriter out = httpServletResponse.getWriter();
out.append(psWindows);
And I read the JSON with
ObjectMapper mapper = new ObjectMapper();
CoverageDO[] coverage = mapper.readValue(foo, CoverageDO[].class);
I suspect the problem is in your timezone.
java.sql.Date stores the date like a timestamp (time since January 1, 1970, 00:00:00 GMT), but when it gets converted to java.util.Date. Try to use SimpleDateFormat to check the real date.
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(date);
tl;dr
LocalDate.parse( "2018-02-27" )
java.time
The java.sql.Date class is part of the troublesome old date-time classes that are now legacy, supplanted by the java.time classes.
LocalDate ld = LocalDate.parse( "2018-02-27" ) ;
LocalTime lt = LocalTime.parse( "10:00:00" ) ;
Generate a string representing that date’s value using standard ISO 8601 format by calling toString.
String output = ld.toString() ;
2018-02-27
Put those two together.
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
ldt.toString(): 2018-02-27T10:00:00
A LocalDateTime lacks any concept of time zone or offset-from-UTC. As such, a LocalDateTime does not represent a moment, is not a point on the timeline. It represents a vague idea of potential moments along a range of about 26-27 hours.
To determine an actual moment, place it into the context of a time zone (or offset) if you are absolutely certain such a zone/offset was intended.
If I convert the sql.Date to a LocalDate
Don’t. No need to ever use java.sql.Date again. Just use LocalDate.
If you must inter-operate with old code not yet updated to java.time classes, then call new conversion methods added to the old classes.
LocalDate ld = myJavaSqlDate.toLocalDate() ; // From legacy class to modern class.
java.sql.Date myJavaSqlDate = java.sql.Date.valueOf( ld ) ; // Vice-versa. From modern class to legacy class.
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.

Java Calendar object, setting date and time separately

When creating a calendar object and setting the date/time using SimpleDateFormat to parse a string, is it possible to set the date and time in two separate lines of code? For example, in my SQLite db the date (mm-dd-yyyy) is stored in a separate column from the time (hh:mm). Is it kosher to do something like the following:
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd-yyyy");
SimpleDateFormat sdfTime = new SimpleDateFormat("hh:mm zzz");
cal.setTime(sdfDate.parse(DATE));
cal.setTime(sdfTime.parse(TIME));
Would the second cal.setTime line reset the date portion of the calendar object to now and just change the time?
Yes it would.
setTime() sets the the time regardless of the fact that a date contained no time value (00:00:00) or no date value (01.01.1970).
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd-yyyy hh:mm zzz");
cal.setTime(sdfDate.parse(DATE+ " " + TIME));
Should work out for you.
tl;dr
ZonedDateTime.of(
LocalDate.parse( "12-23-2015" , DateTimeFormatter.ofPattern( "MM-dd-yyyy") ) ,
LocalTime.parse( "21:43" ) ,
ZoneId.of( "Pacific/Auckland" )
)
.toString()
2015-12-23T21:43+13:00[Pacific/Auckland]
Details
The Answer by Jan is correct.
java.time
Alternatively, you could use the new date-time framework, java.time.
The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
If your inputs lacked an offset-from-UTC, then we could treat the date and the time-of-day separately. The new classes include LocalDate to represent a date-only value without a time-of-day, and LocalTime to represent a time-only value without a date. Then you can combine them and adjust into their intended time zone.
DateTimeFormatter formatterDate = DateTimeFormatter.ofPattern( "MM-dd-yyyy");
LocalDate localDate = LocalDate.parse( "12-23-2015" , formatterDate );
LocalTime localTime = LocalTime.parse( "21:43" );
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( localDate , localTime , zoneId );
But your time string does contain an offset-from-UTC. So we should take the same approach as the Answer by Jan, concatenate the pair of strings and then parse.
String input = "12-23-2015" + " " + "21:43-05:00" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy HH:mmxxx");
ZonedDateTime zdt = ZonedDateTime.parse( input , formatter );
ISO 8601
By the way, in the future when serializing a date, a time, or a date-time to a string such as you did in your SQLite database I strongly recommend using the standard ISO 8601 formats: YYYY-MM-DD, HH:MM, and YYYY-MM-DDTHH:MM:SS.S±00:00. For example, 2007-12-03T10:15:30+01:00. These formats are standardized, easy for humans to read and discern, and easy for computers to parse without ambiguity.
The java.time framework parses and generates strings in these formats by default. Also, java.time extends ISO 8601 by appending the name of the time zone in square brackets. For example, 2007-12-03T10:15:30+01:00[Europe/Paris].
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.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or 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.

Oracle date to Java date

What SimpleDateFormat to use for parsing Oracle date ?
I'm using this SimpleDateFormat.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/mm/dd hh:mm:ss.sss");
its giving this exception.
java.text.ParseException: Unparseable date: "2011-08-19 06:11:03.0"
Kindly please tell me the SimpleDateFormat to use. Thanks.
You should use this Pattern "yyyy-MM-dd HH:mm:ss.S" instead of "yyyy/mm/dd hh:mm:ss.sss".
little h for "Hour in am/pm (1-12)" and H for "Hour in day (0-23)"
see here: SimpleDateFormat
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
Date date = dateFormat.parse("2011-08-19 06:11:03.0");
tl;dr
LocalDateTime.parse(
"2011-08-19 06:11:03.0".replace( " " , "T" )
)
Details
Your input string does not match your formatting pattern. Your pattern has slash characters where your data has hyphens.
java.time
Furthermore, you are using terrible old date-time classes that are now legacy, supplanted by the java.time classes.
Your input string nearly complies with the ISO 8601 standard for date-time formats. Replace the SPACE in the middle with a T.
String input = "2011-08-19 06:11:03.0".replace( " " , "T" ) ;
Your input lacks any indicator of time zone or offset-from-UTC. So we parse as a LocalDateTime, for an object lacking any concept of zone/offset.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
To generate a string in standard format, call toString.
String output = ldt.toString() ;
If this input was intended for a specific time zone, assign it.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( 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.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or 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.

Java Calendar timezone converting to GMT problem

I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
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.
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor 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.

Categories