Figuring Out Local Time with Adding Manual Hour Method in Java - java

Hello I have a method which adds a time to my current time.
What I am looking for is I want to add this code a local time info because doesnt get the local time in my country correctly.
I searched in the stackoverflow but couldnt find a similar topic for this case.
I am open your suggestions, thank you.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class MyClass {
public static void main(String args[]) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 8);
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
System.out.println(dateFormat.format(cal.getTime()));
}
}
I have changed the code with java.time utilities
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class MyClass {
public static void main(String args[]) {
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
LocalDateTime date = LocalDateTime.now();
System.out.println(dateFormat.format(date));
System.out.println(dateFormat.format(date.plusHours(10)));
}
}

tl;dr
ZonedDateTime
.now( ZoneId.of( "Europe/Istanbul" ) )
.plusHours( 10 )
No, not Calendar
Never use the terrible Calendar & SimpleDateFormat legacy classes.
No, not LocalDateTime
Never call LocalDateTime.now. I cannot imagine a case where that is the right thing to do.
The LocalDateTime class lacks the context of a time zone or offset from UTC. So that class cannot represent a moment, a specific point on the timeline.
To track a moment, use: Instant, OffsetDateTime, or ZonedDateTime classes.
ZoneId
Specify your time zone.
ZoneId z = ZoneId.of( "Europe/Istanbul" ) ;
Or get the JVM‘s current default time zone.
ZoneId z = ZoneId.systemDefault() ;
ZonedDateTime
Get the current moment.
ZonedDateTime now = ZonedDateTime.now( z ) ;
Add time.
ZonedDateTime later = now.plusHours( 10 ) ;

Unfortunately you cannot really use the timezone because you get it from your operating system. If the OS gives you UTC, either configure it to Turkey or change it inside the application.
Since you know your location, just do this:
LocalDateTime date = LocalDateTime.now((ZoneId.of("Europe/Istanbul"));
This question from below might help :
how can i get Calendar.getInstance() based on Turkey timezone
You can also deduce your timezone using your internet provider. Below there are 2 examples.
timezone example 1
RestTemplate restTemplate = new RestTemplate();
String timezone = restTemplate.getForObject("https://ipapi.co/timezone", String.class);
timezone example 2
String timezone = restTemplate.getForObject("http://ip-api.com/line?fields=timezone", String.class);
After getting the timezone:
LocalDateTime date = LocalDateTime.now(ZoneId.of(timezone));

Related

Kotlin/java - How to convert a date time string to Instant?

I am trying to create an instance of Instant from date and time strings. Date is formatted like this yyyy-MM-dd. So the values could look like this:
val date = "2021-11-25"
val time = "15:20"
I am trying to make a valid instant from this 2 strings like this:
val dateTime = "${date}T${time}:00"
val instantDateTime = ZonedDateTime.parse(dateTime,
DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(defaultTimeZone)
).toInstant()
I have also tried with it:
val instantDateTime = Instant.from(DateTimeFormatter .ISO_OFFSET_DATE_TIME.withZone(defaultTimeZone).parse(dateTime))
But, that is not working, I get:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-11-25T15:20:00' could not be parsed at index 19
You can combine the date and time strings to create a date-time string in ISO 8601 format which you can parse into LocalDateTime and then convert into Instant by using the applicable ZoneId. Note that the modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class Main {
public static void main(String[] args) {
String strDate = "2021-11-25";
String strTime = "15:20";
String strDateTime = strDate + "T" + strTime;
LocalDateTime ldt = LocalDateTime.parse(strDateTime);
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
System.out.println(instant);
}
}
Output:
2021-11-25T15:20:00Z
ONLINE DEMO
Some alternative approaches:
Create the instance of LocalDateTime can be as suggested by daniu i.e. parse the date and time strings individually and create the instance of LocalDateTime using them.
Demo:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
public class Main {
public static void main(String[] args) {
String strDate = "2021-11-25";
String strTime = "15:20";
LocalDateTime ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime));
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
System.out.println(instant);
}
}
ONLINE DEMO
Create the instance of ZonedDateTime using ZonedDateTime#of(LocalDate, LocalTime, ZoneId) as suggested by Ole V.V.. Another variant that you can try with this approach is by using ZonedDateTime#of(LocalDateTime, ZoneId).
Demo:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
String strDate = "2021-11-25";
String strTime = "15:20";
ZonedDateTime zdt = ZonedDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime),
ZoneId.systemDefault());
// Alternatively
// ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime)),
// ZoneId.systemDefault());
Instant instant = zdt.toInstant();
System.out.println(instant);
}
}
ONLINE DEMO
Combine the date and time strings to create a date-time string in ISO 8601 format and parse the same to ZonedDateTime using DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()).
Demo:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDate = "2021-11-25";
String strTime = "15:20";
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault());
ZonedDateTime zdt = ZonedDateTime.parse(strDate + "T" + strTime, dtf);
Instant instant = zdt.toInstant();
System.out.println(instant);
}
}
ONLINE DEMO
Create an instance of LocalDateTime by parsing the date and time strings, and use the LocalDateTime#toInstant to get the required Instant.
Demo:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
public class Main {
public static void main(String[] args) {
String strDate = "2021-11-25";
String strTime = "15:20";
LocalDateTime ldt = LocalDateTime.of(LocalDate.parse(strDate), LocalTime.parse(strTime));
Instant instant = ldt.toInstant(ZoneId.systemDefault().getRules().getOffset(ldt));
System.out.println(instant);
}
}
ONLINE DEMO
Learn more about the modern Date-Time API* from Trail: Date Time. Check this answer and this answer to learn how to use java.time API with JDBC.
* 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.
Your date string doesn't include a timezone, so it cannot be parsed directly to a ZonedDateTime (see javadoc for ZonedDateTime#parse).
Try parsing the string to a LocalDateTime instead (using LocalDate#parse).
You can then convert the the LocalDateTimeto an Instant using LocalDateTime#toInstant or to a ZonedDateTime using LocalDateTime#atZone

Joda time - get next time it's X o'clock

I need to get the next datetime when it's say, 20.00 o'clock.
So for instance, if it's 13.00 hours, it'd give me the datetime corresponding to today at 20.00.
But if it's 21.00, it'd give me tomorrow at 20.00.
How can I achieve this? Is there some built in function that I just can't find the name of?
In a pinch I could also use Java Time instead of Joda Time.
Add one day to DateTime if the time is past 20:00.
Demo:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
public final class Main {
public static final void main(String[] args) {
// Test
System.out.println(getNextTime("13.00"));
System.out.println(getNextTime("21.00"));
}
static DateTime getNextTime(String strTime) {
LocalTime time = LocalTime.parse(strTime);
DateTime dt = DateTime.now(DateTimeZone.getDefault()).withTime(new LocalTime(20, 0));
if (time.isAfter(new LocalTime(20, 0))) {
dt = dt.plusDays(1);
}
return dt;
}
}
Output:
2021-03-29T20:00:00.000+01:00
2021-03-30T20:00:00.000+01:00
Note: Check the following notice at the Home Page of Joda-Time
Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).
Using the modern date-time API:
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public final class Main {
public static final void main(String[] args) {
// Test
System.out.println(getNextTime("13.00"));
System.out.println(getNextTime("21.00"));
}
static ZonedDateTime getNextTime(String strTime) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH.mm");
LocalTime time = LocalTime.parse(strTime, dtf);
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault()).withHour(20);
if (time.isAfter(LocalTime.of(20, 0))) {
zdt = zdt.plusDays(1);
}
return zdt;
}
}
Output:
2021-03-29T20:00:18.325419+01:00[Europe/London]
2021-03-30T20:00:18.327587+01:00[Europe/London]

String to date sometimes the full date exists sometimes I only get year in java

So am parsing json and sometimes the string I receive which contains the date comes full(dd-mm-yyyy) , and sometimes I only receive yyyy which I dont seem to able to convert to date ,so if anyone can help
As per your business requirement, you can default the month and the day-of-month to the required value using DateTimeFormatterBuilder#parseDefaulting e.g. in the following code, I have defaulted the month and the day-of-month to that of today:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
class Main {
public static void main(String[] args) {
// Test
System.out.println(parseToDate("10-10-2020"));
System.out.println(parseToDate("2020"));
}
static LocalDate parseToDate(String str) {
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("[dd-MM-uuuu][uuuu]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, today.getMonthValue())
.parseDefaulting(ChronoField.DAY_OF_MONTH, today.getDayOfMonth())
.toFormatter(Locale.ENGLISH);
return LocalDate.parse(str, formatter);
}
}
Output:
2020-10-10
2020-12-12
Note: The pattern, [dd-MM-uuuu][uuuu] has two optional patterns, dd-MM-uuuu and uuuu.

Calculate AGE between two java.Util.Date

Folks!
Could any one help me find the way out this situation?
I'm aware that java.util.Date is deprecated, but my work is all based on it.
I'm having trouble to return the age in Years from the User.
I have these two dates:
Date nascimento = dashboard.getDtNascimento();
Date creationTime = new Date(session.getCreationTime());
That first Date come from a ArrayList that contains the user BirthDay.
The second one come from the user session..
How can I return the age having those two Dates? How can I do the math?
Is that any kind of way to parse those Dates into LocalDate perhaps...
Thank you guys!
You can get an Instant from java.util.Date. From the Instant, you can get an OffsetDateTime and from that, you can get a LocalDate. Finally, you can use Period.between to get Period between the LocalDates and from the Period, you can get years.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse("1975-08-27");
Date endDate = sdf.parse("2020-02-15");
OffsetDateTime startOdt = startDate.toInstant().atOffset(ZoneOffset.UTC);
OffsetDateTime endOdt = endDate.toInstant().atOffset(ZoneOffset.UTC);
int years = Period.between(startOdt.toLocalDate(), endOdt.toLocalDate()).getYears();
System.out.println(years);
}
}
Output:
44
Yes, you can convert these to LocalDate like this...
Date creationTime = new Date(session.getCreationTime());
LocalDate localCreationTime = creationTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
If I understand your question you want to find the difference between these dates?
If you convert to LocalDate you can do this:
long age = YEARS.between(localNascimento, localCreationTime);

Get Hijri date from future Gregorian date

How am I able to get hijradate from the code below but instead of now() I would like to get this from a future date.
java.time.chrono.HijrahDate hijradate = java.time.chrono.HijrahDate.now();
System.out.println("hijradate "+hijradate);
It’s straightforward when you know how:
LocalDate gregorianDate = LocalDate.of(2019, Month.FEBRUARY, 22);
HijrahDate hijradate = HijrahDate.from(gregorianDate);
System.out.println(hijradate);
This printed
Hijrah-umalqura AH 1440-06-17
If by Gregorian date you meant that you had your date in a GregorianCalendar object (typically from a legacy API that you cannot change or don’t want to change just now):
GregorianCalendar gregCal = // ...
ZonedDateTime gregorianDateTime = gregCal.toZonedDateTime();
System.out.println(gregorianDateTime);
HijrahDate hijradate = HijrahDate.from(gregorianDateTime);
System.out.println(hijradate);
Output in one run on my computer was:
2019-02-22T00:00+03:00[Asia/Riyadh]
Hijrah-umalqura AH 1440-06-17
EDIT: For the sake of completeness here are my imports so you know exactly which classes I am using:
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.chrono.HijrahDate;
import java.util.GregorianCalendar;
EDIT: To get the month: use your search engine. I used mine and found:
int month = hijradate.get(ChronoField.MONTH_OF_YEAR);
System.out.println(month);
String formattedMonthName
= hijradate.format(DateTimeFormatter.ofPattern("MMMM", new Locale("ar")));
System.out.println(formattedMonthName);
This prints
6
جمادى الآخرة
The last lines are inspired from this answer.

Categories

Resources