Formatting LocalTime Minutes/Seconds into Integer Java - java

I know there are similar questions but they don't answer my problem. I want to format the current time into integer, but only the minutes or seconds.
So for example
LocalTime d = LocalTime.now(ZoneId.of("GMT"));
gives me the current GMT and with "withNano(0)" I can cut off the nanoseconds. Since I have it in the format 12:15:45 now I want to be able to save 15 (Minutes) into my Integer or 45 (Seconds). How can I convert it?

You can call specific methods on the LocalTime such as getMinute() and getSecond(), or you can use a DateTimeFormatter with a pattern that you’re looking for, like:
d.format(DateTimeFormatter.of(“mm:ss”);
If you’re doing that, you don’t need to zero out the nano first.

You can use built in methods for getting minutes and seconds, they both return integers:
d.getMinute();
d.getSecond();

Simply use the getter methods of LocalTime.
import java.time.LocalTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
LocalTime now = LocalTime.now(ZoneOffset.UTC);
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
System.out.printf("%d hour, %d minute, %d second", hour, minute, second);
}
}
Output:
21 hour, 37 minute, 47 second
Also, I suggest you use ZoneOffset.UTC for UTC instead of the 3-letter name for timezone. You can also use ZoneId.of("Etc/UTC"). The general naming convention for timezone is Region/City e.g. Europe/London.

Related

How to get epoch of custom date and time in java?

I want an epoch of every day at 12pm. I have tried to make a function that makes a string of date time and has to convert into an epoch but this doesn't work and also it shows 12pm to 0(zero) I don't know why
here's what I have tried but show error:
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month=now.get(Calendar.MONTH)+1;
int date=now.get(Calendar.DATE);
String yearInString = String.valueOf(year);
String monthInString=String.valueOf(month);
if(monthInString.length()==1){
monthInString="0"+monthInString;
}
String dateInString=String.valueOf(date);
if(dateInString.length()==1){
dateInString="0"+dateInString;
}
int hour=now.get(Calendar.HOUR);
String hourInString=String.valueOf(hour);
int minute=now.get(Calendar.MINUTE);
String minuteInString=String.valueOf(minute);
if(minuteInString.length()==1){
minuteInString="0"+minuteInString;
}
int second=now.get(Calendar.SECOND);
String secondInString=String.valueOf(second);
String HRD=yearInString+"-"+monthInString+"-"+dateInString+" "+hourInString+":"+minuteInString+":"+secondInString;
System.out.println(HRD);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS");
LocalDateTime dt = LocalDateTime.parse(HRD, dtf);
Instant instant = dt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
and also tried this
Date date1 = dateFormat.parse(HRD);
long epoch = date1.getTime();
System.out.println(epoch);
but show error
Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-10-06 0:29:43' could not be parsed at index 11
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494)
at customepoch.main(customepoch.java:35)
java.time
The java.util Date-Time API is outdated and error-prone. It is recommended to stop using it completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API: From the OffsetDateTime at 12 pm, you can get the corresponding Instant using OffsetDateTime#toInstant and from this Instant, you can get the epoch milliseconds.
Demo:
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.temporal.TemporalAdjusters;
public class Main {
public static void main(String[] args) {
OffsetDateTime todayAtNoon = OffsetDateTime.of(LocalDate.now(ZoneOffset.UTC), LocalTime.NOON, ZoneOffset.UTC);
OffsetDateTime lastDateOfMonth = todayAtNoon.with(TemporalAdjusters.lastDayOfMonth());
for (OffsetDateTime odt = todayAtNoon; !odt.isAfter(lastDateOfMonth); odt = odt.plusDays(1)) {
System.out.println(odt.toInstant().toEpochMilli());
}
}
}
Output:
1633521600000
1633608000000
1633694400000
...
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.
What went wrong in your code?
There are already two answers showing you how to obtain the numbers you want. I am not repeating that.
Rather I am posting this answer because I sensed a curiosity: Why did your code show 12 PM as 0 (zero)? Why did you get the error (exception)? This is what I am addressing here.
First as has been said directly or indirectly you were using the Calendar class for obtaining the current time in your time zone. Calendar is poorly designed and long outdated. Don’t do that.
Your conversion from Calendar to Instant was very, very complicated. If you had got a Calendar from some legacy API and wanted to convert it (which you don’t want for your current purpose), all you had needed was:
Instant instant = now.toInstant();
That’s right, since Java 8 Calendar has got a toInstant method for the conversion. The other old date and time classes have got similar conversion methods added.
You tried:
int hour=now.get(Calendar.HOUR);
Calendar.HOUR is for hour within AM or PM from 0 though 11. This explains why you got 0 for 12 PM. Calendar.HOUR_OF_DAY is for hour of day from 0 through 23. It’s just one of the many confusing points about Calendar and one of the many reasons why I recommend you don’t use it.
You prepended month, day of month and minute with 0 to make sure you had got two digits. You didn’t do the same for hour and second. Since your hour was 0, it was only one digit and did not match HH in the format pattern, which requires two digits. This caused the exception that you reported.
You tried this formatter for parsing:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS");
The string you built did not include milliseconds. You should either leave out .SSS or you should add the fraction of second to your string.
This seems to conflict with your intention:
Instant instant = dt.toInstant(ZoneOffset.UTC);
Since you wanted the time in your local time zone, it should have been:
Instant instant = dt.toInstant(ZoneId.systemDefault());
Say you have your local timezone properly set for your JVM so that it is available with ZoneId.systemDefault(). Assume also you start from today (06-Oct-2021). Then your code would be:
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.of(2021, Month.OCTOBER, 6, 12, 0);
for (long i = 0; i < 10; i++) {
System.out.println(
start
.plusDays(i)
.atZone(ZoneId.systemDefault())
.toEpochSecond()
);
}
}

how to change the current date

my method accepts - hours, minutes, seconds and milliseconds separated by sign / as a string parameter
how can I add to the current date the parameters that come to the method.
Example 1: today, 02/10/2021, the method receives metnode data (10/10/10/10) - output - 02/10/2021 10:10:10
Example 2: today, 02/10/2021, the method receives metnode data (55/10/10/10) - output - 02/12/2021 07:10:10
That is, you need to add 55 hours 10 seconds 10 seconds and 10 milliseconds to the current date.
you cannot use the Calendar and StringTokenizer classes.
public void method(String s) {
s = s.replaceAll("/", "-");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
final LocalDateTime now = LocalDateTime.parse(s, formatter.withResolverStyle(ResolverStyle.LENIENT));
System.out.println(now);
}
i found the withResolverStyle (ResolverStyle.LENIENT) method
but did not understand how to use it.
A lenient DateTimeFormatter is enough
I don’t know if it’s the best solution. That probably depends on taste. It does use the ResolverStyle.LENIENT that you mentioned and generally works along the lines of the code in your question, only fixed and slightly simplified.
My formatter includes both date and time. This is necessary for surplus hours to be converted to days.
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-dd H/m/s/")
.appendValue(ChronoField.MILLI_OF_SECOND)
.toFormatter()
.withResolverStyle(ResolverStyle.LENIENT);
Next thing we need a string that matches the formatter. So let’s prepend the date to the time string that we already have got:
String timeString = "55/10/10/10";
LocalDate today = LocalDate.now(ZoneId.of("America/Regina"));
String dateTimeString = "" + today + ' ' + timeString;
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
The output from my code when I ran it today (February 10) was:
2021-02-12T07:10:10.010
A different idea: use Duration
Edit: An alternative is to use the Duration class. A reason for doing that would be that it really appears that you are adding a duration rather than setting the time of day. A liability is that parsing your string into a Duration is a bit tricky. The Duration.parse method that we want to use only accepts ISO 8601 format. It goes like PT55H10M10.010S for a period of time of 55 hours 10 minutes 10.010 seconds. And yes, milliseconds need to be given as a fraction of the seconds.
String isoTimeString = timeString.replaceFirst("(/)(\\d+)$", "$100$2")
.replaceFirst("(\\d+)/(\\d+)/(\\d+)/0*(\\d{3})", "PT$1H$2M$3.$4S");
Duration dur = Duration.parse(isoTimeString);
LocalDateTime dateTime = LocalDate.now(ZoneId.of("Asia/Kathmandu"))
.atStartOfDay()
.plus(dur);
When I ran it just now — already February 11 in Kathmandu, Nepal — the output was:
2021-02-13T07:10:10.010
I am using two calls to replaceFirst(), each time using a regular expression. The first call simply adds some leading zeroes to the milliseconds. $1 and $2 in the replacement string give us what was matched by the first and the second group denoted with round brackets in the regular expression.
The second replaceFirst() call established the ISO 8601 format, which includes making sure that the milliseconds are exactly three digits so they work as a decimal fraction of the seconds.
Link: ISO 8601
Try this:
public void method(String s) {
String[] arr = s.split("/");
LocalDateTime now = LocalDateTime.of(
LocalDate.now(), LocalTime.of(0, 0))
.plusHours(Integer.parseInt(arr[0]))
.plusMinutes(Integer.parseInt(arr[1]))
.plusSeconds(Integer.parseInt(arr[2]))
.plusNanos(Integer.parseInt(arr[3]) * 1_000_000L);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss");
System.out.println(now.format(formatter));
}
Look into the LocalDateTime documentation. It offers various means for combining dates. Such as:
plus(amount, unit)
plusDays(days)
plusHours(hours)
plusMinutes(minutes)
just for simplicity , you can your LocalDateTime class. it is easy to understand. please refer to below code is used to add the hours, minuts, second and nanos to current Date Time.
this Date Time then can easy formatted by any format pattern as required.
public void addDateTime(int hours, int minuts, int seconds, int nanos) {
LocalDateTime adt = LocalDateTime.now();
System.out.println(adt);
adt = adt.plusHours(hours);
adt = adt.plusMinutes(minuts);
adt = adt.plusSeconds(seconds);
adt = adt.plusNanos(nanos);
System.out.println(adt);
}

Java Period.between shows strange output

I am making an application just for learning purpose. And I tried to calculate the difference between two dates
LocalDate today = LocalDate.now();
LocalDate localHoudbaarheid = houdbaarheidsDatum;
Period period = Period.between(today, localHoudbaarheid);
The calculation works, but the output is strange.
Output of the code:
Dagen tot over de datum: P9D
The only thing that should be shown is the 9 without the P and D. This is where I call the name period in my code to print it out:
"Dagen tot over de datum: " + period;
There is nothing whatsoever strange about the output, it is exactly what the documentation, i.e. the javadoc of Period.toString() says it is:
Outputs this period as a String, such as P6Y3M1D.
The output will be in the ISO-8601 period format. A zero period will be represented as zero days, 'P0D'.
As documentation says, the output is following the ISO-8601 standard for durations, as also explained on Wikipedia:
Durations define the amount of intervening time in a time interval and are represented by the format P[n]Y[n]M[n]DT[n]H[n]M[n]S ...
P is the duration designator (for period) placed at the start of the duration representation.
Y is the year designator that follows the value for the number of years.
M is the month designator that follows the value for the number of months.
W is the week designator that follows the value for the number of weeks.
D is the day designator that follows the value for the number of days.
P9D means a Period of 9 Days.
import java.time.LocalDate;
import java.time.Period;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate after9Days = today.plusDays(9);
Period period = Period.between(today, after9Days);
System.out.println(period);
System.out.printf("Years: %d, Months: %d, Days: %d", period.getYears(), period.getMonths(), period.getDays());
}
}
Output:
P9D
Years: 0, Months: 0, Days: 9
Learn more about it at https://en.wikipedia.org/wiki/ISO_8601#Durations
The toString() method of Period outputs something like:
P(nbYears)Y(nbMonths)M(nbDays)D
P9D means a period of 9 days. P4Y3M9D means a period of 4 years, 3 months, and 9 days.
The Period class has utility methods to get this information: getDays(), getMonths(), and getYears().
If you just want to obtain the difference in the unit you choose, prefer using the until() method on the Temporal interface.
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate after3Months9Days = today.plusMonths(3).plusDays(9);
System.out.println(today.until(after3Months9Days, ChronoUnit.DAYS));
}
}
This outputs:
101

Calculate time difference between two times represented as longs

I am trying to calculate the difference between two times, which are represented as longs in the Format HHmm 24 hour time. E.g 4:30pm is represented by the long 0430.
I am happy for the difference to be in minutes.
Is there a simple calculation that can be done to achieve this? I am aware of Java's Date class, however I want to avoid having to store dummy date information just for a calculation on time.
Thanks!
Putting aside the fact that this is a really, really bad way to store times, the easiest way to do this is to convert the HHMM time to minutes since the start of the day:
long strangeTimeFormatToMinutes(long time) {
long minutes = time % 100;
long hours = time / 100;
return minutes + 60 * hours;
}
Then just use plain old subtraction to get the difference.
You may also want to add validation that minutes and hours are in the ranges you expect, i.e. 0-59 and 0-23.
You mentioned that you didn't want to use the Date class because it required you to use a dummy date. The LocalTime class does not require that.
LocalTime start = LocalTime.of(6,15,30,200); // h, m, s, nanosecs
LocalTime end = LocalTime.of(6,30,30,320);
Duration d = Duration.between(start, end);
System.out.println(d.getSeconds()/60);
Pad zeros
First convert your integer to a 4-character string, padding with leading zeros.
For example, 430 becomes 0430 and parsed as 04:30. Or, 15 becomes 0015 and parsed as quarter past midnight, 00:15.
String input = String.format( "%04d", yourTimeAsInteger );
LocalDate
The LocalTime class represents a time-of-day value with no date and no time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "HHmm" );
LocalTime ld = LocalTime.parse( input , f ) ;

How to get milliseconds from LocalDateTime in Java 8

I am wondering if there is a way to get current milliseconds since 1-1-1970 (epoch) using the new LocalDate, LocalTime or LocalDateTime classes of Java 8.
The known way is below:
long currentMilliseconds = new Date().getTime();
or
long currentMilliseconds = System.currentTimeMillis();
I'm not entirely sure what you mean by "current milliseconds" but I'll assume it's the number of milliseconds since the "epoch," namely midnight, January 1, 1970 UTC.
If you want to find the number of milliseconds since the epoch right now, then use System.currentTimeMillis() as Anubian Noob has pointed out. If so, there's no reason to use any of the new java.time APIs to do this.
However, maybe you already have a LocalDateTime or similar object from somewhere and you want to convert it to milliseconds since the epoch. It's not possible to do that directly, since the LocalDateTime family of objects has no notion of what time zone they're in. Thus time zone information needs to be supplied to find the time relative to the epoch, which is in UTC.
Suppose you have a LocalDateTime like this:
LocalDateTime ldt = LocalDateTime.of(2014, 5, 29, 18, 41, 16);
You need to apply the time zone information, giving a ZonedDateTime. I'm in the same time zone as Los Angeles, so I'd do something like this:
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));
Of course, this makes assumptions about the time zone. And there are edge cases that can occur, for example, if the local time happens to name a time near the Daylight Saving Time (Summer Time) transition. Let's set these aside, but you should be aware that these cases exist.
Anyway, if you can get a valid ZonedDateTime, you can convert this to the number of milliseconds since the epoch, like so:
long millis = zdt.toInstant().toEpochMilli();
What I do so I don't specify a time zone is,
System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("ctm " + System.currentTimeMillis());
gives
ldt 1424812121078
ctm 1424812121281
As you can see the numbers are the same except for a small execution time.
Just in case you don't like System.currentTimeMillis, use Instant.now().toEpochMilli()
Since Java 8 you can call java.time.Instant.toEpochMilli().
For example the call
final long currentTimeJava8 = Instant.now().toEpochMilli();
gives you the same results as
final long currentTimeJava1 = System.currentTimeMillis();
To avoid ZoneId you can do:
LocalDateTime date = LocalDateTime.of(1970, 1, 1, 0, 0);
System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
Getting 0 as value, that's right!
You can use java.sql.Timestamp also to get milliseconds.
LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);
To get the current time in milliseconds (since the epoch), use System.currentTimeMillis().
You can try this:
long diff = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli();
Why didn't anyone mentioned the method LocalDateTime.toEpochSecond():
LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);
This seems way shorter that many suggested answers above...
For LocalDateTime I do it this way:
LocalDateTime.of(2021,3,18,7,17,24,341000000)
.toInstant(OffsetDateTime.now().getOffset())
.toEpochMilli()
I think this is more simpler:
ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());
Assert.assertEquals(System.currentTimeMillis(), zdt.toInstant().toEpochMilli());
get the millis like System.currentTimeMillis() (from UTC).
There are some methods available that no one has mentioned here. But I don't see a reason why they should not work.
In case of LocalDate, you can use the toEpochDay() method. It returns the number of days since 01/01/1970. That number then can be easily converted to milliseconds:
long dateInMillis = TimeUnit.DAYS.toMillis(myLocalDate.toEpochDays());
Documentation can be found here.
In case of LocalDateTime, you can use the toEpochSecond() method. It returns the number of seconds since 01/01/1970. That number then can be converted to milliseconds, too:
long dateTimeInMillis = TimeUnit.SECONDS.toMillis(myLocalDateTime.toEpochSeconds());
Documentation for that is here.
If you have a Java 8 Clock, then you can use clock.millis() (although it recommends you use clock.instant() to get a Java 8 Instant, as it's more accurate).
Why would you use a Java 8 clock? So in your DI framework you can create a Clock bean:
#Bean
public Clock getClock() {
return Clock.systemUTC();
}
and then in your tests you can easily Mock it:
#MockBean private Clock clock;
or you can have a different bean:
#Bean
public Clock getClock() {
return Clock.fixed(instant, zone);
}
which helps with tests that assert dates and times immeasurably.
Date and time as String to Long (millis):
String dateTimeString = "2020-12-12T14:34:18.000Z";
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime localDateTime = LocalDateTime
.parse(dateTimeString, formatter);
Long dateTimeMillis = localDateTime
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
default LocalDateTime getDateFromLong(long timestamp) {
try {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
} catch (DateTimeException tdException) {
// throw new
}
}
default Long getLongFromDateTime(LocalDateTime dateTime) {
return dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli();
}

Categories

Resources