Java how to add time and date - datetime

Using JDK 1.8
I have Time in ms for a day (not since 1970) and I have a Date how do I add the two and create a datetime.
Thanks
Tried #Kikos soln does not produce correct result:
Somehow my orig time 930 hrs in this case changes to 9:40, the orig date itself should not have any time gets time (??) - so the addition math fails.
String testdate = "2015/10/25";
Date date = new SimpleDateFormat("yyyy/mm/dd").parse(testdate);
String timehrs= "930";
long ltime = Long.parseLong("930");
long hoursAsSeconds = (ltime / 100) * 60 * 60;
long minsAsSeconds = (ltime % 100) * 60;
long secondsOfDay = hoursAsSeconds + minsAsSeconds;
System.out.println("testdate : "+ testdate +", timehrs: "+timehrs+" ,secondsOfDay: "+secondsOfDay);
System.out.println("Orig Date time formatted: "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(date));
Date dt = new Date(date.getTime() + secondsOfDay*1000);
System.out.println("New Date : "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(dt);
testdate : 2015/10/25, timehrs: 930, secondsOfDay: 34200
Orig Date time formatted: 2015-10-25 12:10:00
New Date : 2015-40-25 09:40:00
Expected : 2015-10-25 09:30:00
Based on below by #Basil Bourque
long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( secondsOfDay*1000 );
LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay );
ZoneId z = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
System.out.println("ZonedDateTime zdt: "+ zdt);
ZonedDateTime zdt: 2015-10-25T09:30-07:00[America/Los_Angeles]
This is the correct answer: 2015-10-25T09:30

Question is convoluted
You say you have time of day as a count of milliseconds since midnight (apparently). Yet 930 would mean the time 00:00:00.930, not 09:30:00 as shown in your example data. I will follow your text rather than your example data.
java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes. Forget you ever heard of java.util.Date and .Calendar.
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 );
ISO 8601
The java.time classes use the ISO 8601 standard by default when parsing/generating strings representing date-time values. To make your input string standard, replace those slash characters with hyphens.
String input = "2015/10/25".replace( "/" , "-" );
LocalDate ld = LocalDate.parse( input );
By the way, this whole scheme you have been assigned is awkward, error-prone, and needlessly complicated. To serialize a date-time value for communication between systems, use the ISO 8601 string formats.
LocalTime
You say you have a count of milliseconds to represent the time of day as a count from midnight.
The LocalTime class offers factory methods to instantiate based on a duration of whole seconds and of nanoseconds. To get nanoseconds, simply multiply your milliseconds by one thousand. Better yet, let the TimeUnit enum do the work and make your code more self-documenting.
long millisOfDay = Long.parseLong( "930" );
long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( millisOfDay ); // Same effect as: ( millisOfDay * 1_000L )
LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay );
ZonedDateTime
Now combine these two Local… objects along with a time zone to determine a point on the timeline. Was this date and time meant to be a moment in Montréal Québec, Paris France, Kolkata India, or Aukland New Zealand?
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
See live code in IdeOne.com.
ld.toString(): 2015-10-25
lt.toString(): 00:00:00.930
zdt.toString(): 2015-10-25T00:00:00.930+13:00[Pacific/Auckland]
LocalDateTime
If your data came with no information about time zone, and you cannot safely assume the intended time zone by your business scenario, you are left with no better option than combining into a LocalDateTime object. But keep in mind that this value is ambiguous. This value is not a point on the timeline. This value represents potential points on the timeline which can only be determined with a time zone assigned for ZonedDateTime or a offset-from-UTC assigned for OffsetDateTime.
LocalDateTime ldt = LocalDateTime.of( ld , lt );
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.

something like:
Date dt = new Date(System.currentTimeMillis() + ms);
or
Date otherDate(....);
Date dt = new Date(otherDate.getTime() + ms);

Related

Java 8, time is not being converted

I'm using Hibernate 5 & MySQL.
This is what is getting saved into the database: 2018-03-11 06:26:47.336 I don't think this is 24 hour format, but then how do I see AM/PM? And how do I save the time in 24 hour format?
Running SELECT ##global.time_zone; in MySQL shows me: +00:00 So I think I'm set for accepting UTC time? This is how I set my pojo's field for setting time:
Clock clock = Clock.systemUTC();
LocalDateTime userCreated = LocalDateTime.now(clock);
It accepts LocalDateTime. But what I get back from database when I query is: u1.getUserCreated(): 2018-03-11T01:26:47.336 And when I try to convert the time into zone specific, I get the below:
ZonedDateTime z1 = ZonedDateTime.of(u1.getUserCreated(), ZoneId.of("America/New_York"));
System.out.println("z1: " + z1);
// z1: 2018-03-11T01:26:47.336-05:00[America/New_York]
But it really should be: 9:26:47.336 PM (21:26:47.336) As you can see on this site: http://www.timebie.com/std/utc.php
You're just not converting correctly. Your LocalDateTime represents the wall-clock time in the UTC time zone. Not in the New York time zone. So yo need to transform it to a ZonedDateTime in UTC::
ZonedDateTime utcDateTime = u1.getUserCreated().atZone(ZoneOffset.UTC);
Then, if you want to get a ZonedDateTime for the same instant, but in the New York timezone, then, well, just do that:
ZonedDateTime newYorkDateTime = utcDateTime.withZoneSameInstant(ZoneId.of("America/New_York"));

How to customize the TemporalAdjusters in Java 8?

I am working with Java 8 Date and Time utility. I am using the TemporalAdjuster interface and the implementations found in TemporalAdjusters to manipulate the calculations for a specific day or date.
My requirement is to calculate the day after 3 month and 2 days.
For example, today is 6th of Decemeber (i.e 2016-12-06 in YYYY-MM-DD) and after 3 months and 2 days, the date would be 8th of March, 2017 (i.e. 2017-03-08 in YYYY-MM-DD).
I tried two ways of doing this using the Date and Time utility as follows:
//First
LocalDate dayAfter3MonthsAnd2Days = LocalDate
.now()
.with(firstDayOfNextMonth()).plusMonths(2).plusDays(2);
//Second
LocalDate dayAfter3MonthsAnd2Days = LocalDate
.now()
.with(firstDayOfMonth()).plusMonths(3).plusDays(2);
Both of them returns the date as 3rd of March, 2017 (i.e. 2017-03-03) as follows:
dayAfter3MonthsAnd2Days = 2017-03-03
Is there any way i can customize the TemporalAdjusters and get the desired output? Or any other alternate to achieve the goal?
I found out that i can simply use the following:
LocalDate dayAfter3MonthsAnd2DaysNew = LocalDate
.now()
.plusMonths(3)
.plusDays(2);
Alongwith that, i can also use the custom TemporalAdjuster which uses the above same process to do manipulations as follows:
TemporalAdjuster ta = TemporalAdjusters.ofDateAdjuster(
(LocalDate d) -> d.plusMonths(3).plusDays(2));
LocalDate dayAfter3MonthsAnd2DaysCustom = LocalDate
.now()
.with(ta);
Although the previous way is simpler, but we can use more custom proceedings using ofDateAdjuster method of TemporalAdjuster.

How to check cutoff time before or after the current time instance?

Currently i am working with shipping condition. in this i will get cut off time against the company like (05.00 PM) .
Now i want to compare above time with current time whether it is before cut off time or after cut off time?
I have gone through all the link i can see only example with date. i could not find anything with time.
Please let me know or give a some clue so that i will sorted out.
This is What i have tried so far
String todayDate=LocalDate.now().toString("dd.MM.yyyy");
String s=todayDate+cutOffTime;//cutOffTime will get from DB
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd.MM.yyyy HH:mm a");
LocalDate despatchDate=LocalDate.now();
try {
Date cutoffDate=simpleDateFormat.parse(s);
if (cutoffDate.after(Calendar.getInstance().getTime())){
despatchDate.plusDays(1);
}
} catch (ParseException e) {
e.printStackTrace();
}
Java 8 date/time api
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDate currentDate = LocalDate.now();
String cutOff = "05:00 AM";
DateTimeFormatter timeParser = DateTimeFormatter.ofPattern("hh:mm a");
LocalTime cutOffTime = timeParser.parse(cutOff, LocalTime::from);
LocalDateTime cutOffDateTime = LocalDateTime.of(currentDate, cutOffTime);
//After
cutOffDateTime.isAfter(currentDateTime);
//Before
cutOffDateTime.isBefore(currentDateTime);
//Compare
cutOffDateTime.compareTo(currentDateTime);
Time Zone
The Answer by Shiv V is going in the right direction, but is not spot-on. The answer ignores the crucial issue of time zone. The Local… types intentionally lose and ignore time zone information, that is their purpose. But we rarely want to lose time zone info.
Determining the date and time-of-day depends on time zone. For any given moment, the date and time can vary around the globe. A few minutes after midnight in Paris is a new day while still “yesterday” in Montréal.
The Instant class defines a moment on the timeline in UTC with a resolution of nanoseconds.
Instant now = Instant.now();
If the desired deadline is “5 PM tomorrow”, you must specify the time zone as the context. Apply a ZoneId to an Instant to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime zdtTomorrow = zdt.plusDays( 1 );
Now adjust to 5 PM.
LocalTime timeOfDayWhenDue = LocalTime.of( 5 , 0 );
ZonedDateTime zdtDeadline = zdtTomorrow.with( timeOfDayWhenDue );
You can compare using the isEqual, isBefore, and isAfter methods.
ZonedDateTime now = ZonedDateTime.now( zoneId );
boolean overdue = now.isAfter( zdtDeadline );
You could also convert the zoned date-times back to UTC. The ZonedDateTime objects and their respective Instant objects represent the same simultaneous moment on the timeline (same moment in history), but seen from the viewpoint of different time zones (America/Montreal versus UTC).
Instant instantDeadline = zdtDeadline.toInstant();
Instant instantNow = now.toInstant();
boolean overdue = instantNow.isAfter( instantDeadline );
If you want to communicate the deadline to a customer in India, adjust into another time zone. The date-time value will represent the same moment on the timeline but will display with a wall-clock time that has meaning for that customer.
ZoneId zoneId_Kolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtDeadline_Kolkata = zdtDeadline.withZoneSameInstant( zoneId_Kolkata );
If you do not specify time zones, the JVM’s current default time zone is applied implicitly, silently. Not good. For one thing, implicit assumptions make your code easy-to-misunderstand and makes bugs more difficult to pinpoint. Worse, the default can change at any time, when you deploy to a different computer, or even during runtime at any moment of your app’s execution! Better to always specify the desired/expected time zone. By the way, same goes for Locale.

Does Joda-Time `DateTime` class have methods such as setHours()/setMinutes() as is available in Javascript Date object

I would like to set hours/minutes/seconds manually in DateTime class from Joda-Time library. What I am trying to do is keep year/month/day value but discard hours/minutes/seconds from date object.
DateTime today = new DateTime();
today.??? (method to call set hours/minutes/seconds to 0)
Happy new year to all!
Immutable Objects
Joda-Time uses immutable objects by default. Rather than call a setter method to change (“mutate”) a member variable, we call a method to generate a new instance based largely on the original.
withTime
To create a new DateTime with a certain time-of-day, call the withTime method.
DateTime now = DateTime.now( DateTimeZone.forID( "America/Montreal" ) );
DateTime lunchtimeToday = now.withTime( 12, 30, 0, 0 ); // Half-past noon.
First Moment Of The Day
If you want midnight (first moment of the day), call withTimeAtStartOfDay. Usually this is 00:00:00.000 but not always.
DateTime todayStart = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Time Zone Is Crucial
Note that time zone is crucial to determining when a day starts. 'Today' in Paris starts sooner than it does in Montréal.
If you omit the time zone, your JVM’s current default time zone will be applied automatically. Better to specify than rely implicitly on this default.
Use proper time zone names. Avoid the 3 or 4 letter codes that are neither standardized not unique.

How can I convert java.util.Date to org.joda.time.DateTime?

I have to use java.util.Date class as field type in a table.
But I would like to change the display format of the date field with help of joda time (confortable, prefered to use), thats why I want to convert a Date to DateTime.
I know I oversee something, because there is no such a question in stackoverflow :) but I could not find the soulution among the DateTime constructors and so on.
The reverse conversion DateTime.toDate();
exists, but what about the opposite way ?
Thanks for the answers in advance.
Cs
In Vaadin, if you want to change display format in a table without joda, you simply override the method protected String formatPropertyValue(Object rowId, Object colId,
Property property)
Here an example to do it :
Table t = new Table() {
#Override
protected String formatPropertyValue(Object rowId, Object colId,
Property property) {
Object v = property.getValue();
if (v instanceof Date) {
Date dateValue = (Date) v;
return new SimpleDateFormat("yyyy-MMMM-dd").format(dateValue);
}
return super.formatPropertyValue(rowId, colId, property);
}
};
Regards
Éric
Yes, Use Joda-Time
Definitely use Joda-Time or the java.time package in Java 8 (inspired by Joda-Time). The old java.util.Date and java.util.Calendar classes are notoriously troublesome, confusing, and outmoded.
Also, read the Wikipedia pages on UTC and ISO 8601.
Yes, Pass Date To Joda-Time Constructor
➔ Yes indeed, you can pass a java.util.Date object to the constructor of a Joda-Time DateTime object.
The API doc is a bit confusing as this apparently falls into the catch-all version of the constructor taking an java.lang.Object instance. If that Object is in fact a java.util.Date, Joda-Time will extract its millisecond-count-since-epoch and use that number as its own.
Time Zone
A DateTime constructor also assigns a time zone. By default, the JVM’s current default time zone is assigned. I recommend you always pass a desired time zone rather than rely implicitly on the default even if that means calling getDefault.
Example Code
Here is some example code in Joda-Time 2.5 showing how to pass a java.util.Date to a Joda-Time constructor.
java.util.Date date = new java.util.Date();
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTimeMontreal = new DateTime( date , zone );
DateTime dateTimeUtc = dateTimeMontreal.withZone( DateTimeZone.UTC ); // Adjust to another time zone.
Dump to console.
System.out.println( "date: " + date ); // Misleading output. A j.u.Date is in UTC but its toString method applies JVM’s current default time zone.
System.out.println( "dateTimeMontreal: " + dateTimeMontreal );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run.
date: Sat Oct 18 18:54:55 PDT 2014
dateTimeMontreal: 2014-10-18T21:54:55.740-04:00
dateTimeUtc: 2014-10-19T01:54:55.740Z
As shown in the Question, to go from a DateTime to java.util.Date, call toDate.
java.util.Date date = dateTimeMontreal.toDate();

Resources