How to get difference of months from Dates in Scala? - java

I have one date in format of date = "2022-07-03 10:09:19"
Need to get difference of months from Today date and time

You can leverage java.time library. Here is a sample code snippet:
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
val dateOld = "2022-07-03 10:09:19".replace(" ", "T")
val dateNew = "2022-11-03 10:09:19".replace(" ", "T")
val l1 = LocalDateTime.parse(dateOld)
val l2 = LocalDateTime.parse(dateNew)
val months = ChronoUnit.MONTHS.between(l1, l2)
For calculating from current time you can use:
val date = "2021-07-03 10:09:19".replace(" ", "T")
val l1 = LocalDateTime.parse(date)
val l3 = LocalDateTime.now()
val months = ChronoUnit.MONTHS.between(l1, l3)
Hope this helps !!

Use ChronoUnit to solve it
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime previousDate = LocalDateTime.parse(date, formatter);
LocalDateTime now = LocalDateTime.now();
long diffMonths = ChronoUnit.MONTHS.between(now, previousDate);

Use java.time if possible
You can parse the datetime String, add a time zone and take the current day or moment in the same time zone. Then you can extract the date and calculate the Period.between those two.
Here's an example in Java:
public static void main(String[] args) {
// example input
String someTime = "2022-07-03 10:09:19";
// prepare a formatter that can parse such a String
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
// prepare the time zone
// (I will use UTC, but the zone depends on the one of the input)
ZoneId utc = ZoneId.of("UTC");
// parse the String, apply the zone and directly extract the date
LocalDate then = LocalDateTime.parse(someTime, dtf)
.atZone(utc)
.toLocalDate();
// get the date of today in the zone
LocalDate today = LocalDate.now(utc);
// calculate the period between the two dates
long months = ChronoUnit.MONTHS.between(then, today);
// prepare some meaningful message to be printed
String msg = String.format(
"The difference in months between %s (then) and %s (today) is %d months",
then, today, months);
// and actually print it
System.out.println(msg);
}
Output:
The difference in months between 2022-07-03 (then) and 2022-08-03 (today) is 1 months

Parse the given date to an instance of java.time.LocalDateTime, then you can get an instance of java.time.Period for the two dates, and from that, you can get the months.
In Java:
final DateTimeFormatter parser = … // An appropriate parser for the given format
final var otherDate = LocalDateTime.parse( dateString, parser );
final var deltaPeriod = Period.between( LocalDateTime.now(), otherDate );
final var result = deltaPeriod.getYears() * 12 + deltaPeriod.getMonths(); // or use Period::toTotalMonths()

Related

Calculate Number of Days between Given time in ISO format and Current time

I have to find out number of days between a given Time and current time. Given time is in ISO format and one example is "2021-01-14 16:23:46.217-06:00".
I have tried it using "java.text.SimpleDateFormat" but it's not giving me accurate results.
In Below Given date, for today's time I am getting output as "633" Days which isn't correct. somehow after parsing it is taking date as "21 december 2020" which isn't correct
String TIMESTAMP_FORMAT = "YYYY-MM-DD hh:mm:ss.s-hh:mm" ;
int noOfDays = Utility.getTimeDifferenceInDays("2021-01-14 16:23:46.217-06:00", TIMESTAMP_FORMAT);
public static int getTimeDifferenceInDays(String timestamp, String TIMESTAMP_FORMAT) {
DateFormat df = new SimpleDateFormat(TIMESTAMP_FORMAT);
try {
Date date = df.parse(timestamp);
long timeDifference = (System.currentTimeMillis() - date.getTime());
return (int) (timeDifference / (1000*60*60*24));
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
Looking for a better solution which gives me correct number of days. Thanks
Use java.time API
Classes Date and SimpleDateFormat are legacy.
Since Java 8 (which was released 10 years ago) we have a new Time API, represented by classes from the java.time package.
To parse and format the data, you can use DateTimeFormatter. An instance of DateTimeFormatter can be obtained via static method ofPattern(), or using DateTimeFormatterBuilder.
ofPattern():
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSXXX");
DateTimeFormatterBuilder:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss.") // main date-time part
.appendValue(ChronoField.MILLI_OF_SECOND, 3) // fraction part of second
.appendOffset("+HH:MM", "+00:00") // can be substituted with appendPattern("zzz") or appendPattern("XXX")
.toFormatter();
The string "2021-01-14 16:23:46.217-06:00", which you've provided as an example, contains date-time information and UTC offset. Such data can be represented by OffsetDateTime.
To get the number of days between two temporal objects, you can use ChronoUnit.between() as #MC Emperor has mentioned in the comments.
That's how the whole code might look like:
String toParse = "2021-01-14 16:23:46.217-06:00";
OffsetDateTime dateTime = OffsetDateTime.parse(toParse, formatter);
System.out.println("parsed date-time: " + dateTime);
Instant now = Instant.now();
long days = ChronoUnit.DAYS.between(dateTime.toInstant(), now);
System.out.println("days: " + days);
Output:
parsed date-time: 2021-01-14T16:23:46.217-06:00
days: 615
Note that since in this case you need only difference in days between the current date instead of OffsetDateTime you can use LocalDateTime, UTC offset would be ignored while parsing a string. If you decide to do so, then the second argument passed to ChronoUnit.between() should be also of type LocalDateTime.

How to convert from string format of date (dd/mm/yyyy) to string format of date (yyyy-mm-dd'T'HH:mm:ss.SSS)

I have to convert
"fromTime" : "04-10-2021"`
to
"fromTime" : "2021-10-04T00:00:00.000"
and
"toTime" : "06-10-2021"
to
"toTime" : "2021-10-06T23:59:59.000"
in java . Help please!
Generally speaking, you really want to avoid representing date/time as String where ever possible.
Displaying date/time values to the user should be done in styles that respect their localisation and transmitting date/time values using JSON or XML should use common/standardised formats. This reduces a LOT of issues (don't even get me started)
For example, had I the choice, I would prefer to use ISO_LOCAL_DATE (uuuu-MM-dd) and ISO_LOCAL_DATE_TIME (uuuu-MM-dd'T'HH:mm:ss). I'm already worried about the lack of time zone information 😱
A "simple" approach might be to do something like...
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu.SSS");
LocalDateTime locatDateTime = LocalDate
.parse("04-10-2021", dateFormatter)
.atTime(0, 0, 0, 0);
String dateAndTime = locatDateTime.format(timeFormatter);
System.out.println(dateAndTime);
locatDateTime = LocalDate
.parse("04-10-2021", dateFormatter)
.atTime(23, 59, 59, 0);
dateAndTime = locatDateTime.format(timeFormatter);
System.out.println(dateAndTime);
Basically...
Parse the date value through a DateTimeFormatter using a matching format patten
Convert the LocalDate to a LocalDateTime by passing in the values we want to use
Format the LocalDateTime through a DateTimeFormatter to the desired format
which prints...
04-10-2021T00:00:00.000
06-10-2021T23:59:59.000
See:
The date/time trail
Introduction to the Java 8 Date/Time API
for more details
Now, if all you really want to do, is make it "start of" and "end of" day, you might be able to use...
LocalDateTime startOfDay = LocalDate
.parse("04-10-2021", dateFormatter)
.atStartOfDay();
LocalDateTime endOfDay = LocalDate
.parse("06-10-2021", dateFormatter)
.plusDays(1)
.atStartOfDay()
.minusSeconds(1);
Right about now, I'd be starting a utility class of some kind which had a method which could take a date String (and possibly an optional format) and generate a LocalDate and then another method which could take LocalDate which could convert it to a LocalDateTime at either the startOfDay or endOfDay
You have to do these steps:
create a DateTimeFormatter for dd-MM-yyyy
parse the date with LocalDate.parse with atTime
create a DateTimeFormatter for yyyy-MM-dd'T'HH:mm:ss.SSS
format the date in order to have the final result
public String changeFormatDate(String date, int hour, int minute, int second, int nanoOfSecond) {
DateTimeFormatter formatterFrom = DateTimeFormatter.ofPattern("dd-MM-yyyy"); // 1
LocalDateTime localDateTimeFrom = LocalDate.parse(date, formatterFrom).atTime(hour, minute, second, nanoOfSecond); // 2
DateTimeFormatter formatterTo = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS"); // 3
return localDateTimeFrom.format(formatterTo); //4
}
Call example:
String fromTime = changeFormatDate("04-10-2021", 0, 0, 0, 0);
String toTime = changeFormatDate("06-10-2021", 23, 59, 59, 999999999);
Here's an example using java.time:
public static void main(String[] args) {
// input dates / days
String fromDate = "04-10-2021";
String toDate = "06-10-2021";
// prepare the times of day
LocalTime startOfDay = LocalTime.MIN; // 00:00:00.000
LocalTime endOfDay = LocalTime.of(23, 59, 59); // 23:59:59.000
// create an object that takes care of parsing the expected format
DateTimeFormatter customDateParser = DateTimeFormatter.ofPattern("dd-MM-uuuu");
// then parse the dates using the formatter / parser
LocalDate fromDay = LocalDate.parse(fromDate, customDateParser);
LocalDate toDay = LocalDate.parse(toDate, customDateParser);
// then concatenate the parsed dates with the prepared times of day
LocalDateTime fromTime = LocalDateTime.of(fromDay, startOfDay);
LocalDateTime toTime = LocalDateTime.of(toDay, endOfDay);
// finally define a formatter for the String output of the LocalDateTimes
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS");
// and print their toString() methods
System.out.println("from " + fromTime.format(customFormatter)
+ " to " + toTime.format(customFormatter));
}
from 2021-10-04T00:00:00.000 to 2021-10-06T23:59:59.000

How to combine String date and String time into a single Instant datetime using Java? [duplicate]

This question already has answers here:
How to combine date and time into a single object?
(3 answers)
Closed 3 years ago.
I want to combine String date("19801115") and String time("1530") into a single Instant datetime.
For example:
There are two String variables:
String applicationDate = "19801115";
String applicationTime = "1530";
And combine them into the applicationDateTime(Instant type, ex: "1980-11-15T15:30:00Z").
How do I achieve that? Thanks.
String dateString = "19801115";
String timeString = "1530";
Date date = null;
try {
date = new SimpleDateFormat("yyyyMMddhhmm").parse(dateString + timeString);
} catch (ParseException e) {
e.printStackTrace();
}
Instant reqInstant = date.toInstant();
System.out.println(reqInstant); // time here depends on your local settings, may differ from 15:30
// this way you adjust an Instant to a time zone you need
ZonedDateTime zdt = ZonedDateTime.ofInstant(reqInstant, ZoneId.systemDefault() /*<- needed time zone here*/);
System.out.println(zdt.toInstant()/*returns an Instant*/);
Additionally, similar functionality with DateTimeFormatter :
String dateString = "19801115";
String timeString = "1530";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("yyyyMMddHHmm")
.toFormatter()
.withZone(ZoneId.systemDefault() /*<- needed time zone here*/);
ZonedDateTime zdtOriginal = ZonedDateTime.parse(dateString + timeString, dtf);
System.out.println(zdtOriginal.toInstant()/*returns an Instant*/);
// this way you adjust an Instant to a time zone you need
ZonedDateTime zdt = zdtOriginal.withZoneSameLocal(ZoneId.of("GMT") /*<- needed time zone here*/);
System.out.println(zdt.toInstant()/*returns an Instant*/);

Convert string local date with zoneId to UTC Offsetdate JAVA

I'm trying to convert a Brazil local date to UTC format. I have developed my solution but I'm sure that it can be improved. I have been searching for others questions but without success.
My problem is that when I process the Date object with:
Instant endDateTime = questionDate.toInstant();
I receive a UTC date as "2017-11-16T00:00:00Z" but this should be Brazil local date (not correct because it has a trailing "Z") and when I try to convert to UTC, I receive the same output.
In another hand, if I use ZoneDateTime class and build the date with LocalDateTime object I lose the seconds in the output: "2017-11-16T02:00Z". This happens when I use:
LocalTime.of(hour, minutes, seconds);
I search into LocalTime class and I think this is because minutes or seconds are 0 but I'm not sure of it.
Problems of the solution:
The response hasn't seconds
I hope Java 8 has a set of functions to make this more simple and clear
Precondition:
I can't use Joda library
Result has to be OffsetDateTime class
Input: Date "2017-11-16"
Output: "2017-11-16T02:00:00Z"
This is my solution:
private static OffsetDateTime processDate(Date questionDate) {
Instant endDateTime = questionDate.toInstant();
ZoneId zoneId = ZoneId.of(ZONEID);
String [] date = endDateTime.toString().split("T");
LocalDateTime localDateTime = convertLocalTimeToUtc(date);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
ZonedDateTime utcDate = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC);
return utcDate.toOffsetDateTime();
}
private static LocalDateTime convertLocalTimeToUtc(String[] dateFromCountry) {
LocalDate date = processDate(dateFromCountry[0]);
LocalTime time = processTime(dateFromCountry[1]);
return LocalDateTime.of(date, time);
}
private static LocalDate processDate(String dateFromCountry) {
String [] partsOfDate = dateFromCountry.split("-");
int year = Integer.parseInt(partsOfDate[0]);
int month = Integer.parseInt(partsOfDate[1]);
int day = Integer.parseInt(partsOfDate[2]);
return LocalDate.of(year, month, day);
}
private static LocalTime processTime(String dateFromCountry) {
String [] partsOfTime = dateFromCountry.split(":");
int hour = Integer.parseInt(partsOfTime[0]);
int minutes = Integer.parseInt(partsOfTime[1]);
int seconds = Integer.parseInt(partsOfTime[2].substring(0,1));
return LocalTime.of(hour,minutes,seconds);
}
If your input is a java.util.Date, you can get rid of all the string manipulation:
//simulate your input
Instant input = Instant.parse("2017-11-16T00:00:00Z");
Date d = Date.from(input);
//transformation code starts here
Instant instant = d.toInstant();
ZonedDateTime localInstant = instant.atZone(ZoneOffset.UTC);
ZonedDateTime sameLocalInBrazil = utcInstant.withZoneSameLocal(ZoneId.of("Brazil/East"));
OffsetDateTime sameInstantUtc = sameLocalInBrazil.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
This return an OffsetDateTime with value 2017-11-16T02:00Z as you expect.
Note that an OffsetDateTime has no formatting - so the object does know that its seconds are set to 0 but the default toString method doesn't print them. If you want to print it with seconds, you can use a formatter:
//Formatting
System.out.println(sameInstantUtc.format(DateTimeFormatter.ISO_INSTANT));
which prints 2017-11-16T02:00:00Z
If your input is a java.sql.Date, you can use a slightly different strategy:
LocalDate d = sqlDate.toLocalDate();
ZonedDateTime localInstant = d.atStartOfDay(ZoneOffset.UTC);
The rest of the code would be the same.

How can I convert a date in YYYYMMDDHHMMSS format to epoch or unix time?

EDIT: I have edited my question to include more information, I have tried many ways to do this already, asking a question on StackOverflow is usually my last resort. Any help is greatly appreciated.
I have a date (which is a Timestamp object) in a format of YYYYMMDDHHMMSS (e.g. 20140430193247). This is sent from my services to the front end which displays it in the format: date:'dd/MM/yyyy' using AngularJS.
How can I convert this into Epoch/Unix time?
I have tried the duplicate question that is linked to this, what I get returned is a different date.
I have also tried the following:
A:
//_time == 20140430193247
return _time.getTime()/1000; // returns 20140430193 - INCORRECT
B:
return _time.getTime(); // returns 20140430193247 (Frontend: 23/03/2608) - INCORRECT
C:
Date date = new Date();
//_time = 20140501143245 (i.e. 05/01/2014 14:32:45)
String str = _time.toString();
System.out.println("Time string is " + str);
//Prints: Time string is 2608-03-24 15:39:03.245 meaning _time.toString() cannot be used
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
date = df.parse(str);
} catch (ParseException e) {
}
return date; // returns 20140501143245 - INCORRECT
D:
date = new java.sql.Date(_time.getTime());
return date; // returns 2608-03-24 - INCORRECT
The following shows the todays date correctly:
Date date = new Date();
return date; // returns 1398939384523 (Frontend: 01/05/2014)
Thanks
I got the answer after quite a while of trying different ways. The solution was pretty simple - to parse the time to a string as toString() didn't work.
Date date;
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
try {
date = df.parse(String.valueOf(_time.getTime()));
} catch (ParseException e) {
throw new RuntimeException("Failed to parse date: ", e);
}
return date.getTime();
tl;dr
LocalDateTime
.parse(
"20140430193247" ,
DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" )
)
.atOffset(
ZoneOffset.UTC
)
.toEpochSecond()
java.time
Parse your input string as a LocalDateTime as it lacks an indicator of offset-from-UTC or time zone.
String input = "20140430193247" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
Now we have a date with time-of-day, around half-past 7 PM on April 30 of 2014. But we lack the context of offset/zone. So we do not know if this was 7 PM in Tokyo Japan or 7 PM in Toledo Ohio US, two different moments that happened several hours apart.
To determine a moment, you must know the intended offset/zone.
If you know for certain that an offset of zero, or UTC itself, was intended, apply the constant ZoneOffset.UTC to get an OffsetDateTime.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
How can I convert this into Epoch/Unix time?
Do you mean a count of seconds or milliseconds since the first moment of 1970 in UTC?
For a count of whole seconds since 1970-01-01T00:00Z, interrogate the OffsetDateTime object.
long secondsSinceEpoch = odt.toEpochSecond() ;
For milliseconds, extract a Instant object. An Instant represents a moment in UTC, and is the basic building-block class of java.time. Then interrogate for the count.
Instant instant = odt.toInstant() ;
long millisSinceEpoch = instant.toEpochMilli() ;

Categories