The code below seems to convert to BST instead. Am I doing something silly?
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class Test {
#Test
public void testTimeInterval(){
String DAY_SHIFT="08:00-17:15";
System.out.println(toInterval(DAY_SHIFT, "America/New_York", "UTC"));
}
public static final String TIME_FORMAT = "HH:mm";
public static List<LocalTime> toInterval(String str, String sourceTZ, String destTZ) {
if (!StringUtils.isBlank(str)){
final DateTimeFormatter timeFormat = DateTimeFormat.forPattern(TIME_FORMAT).withZone(DateTimeZone.forID(sourceTZ));
String[] tokens = str.split("-");
if (tokens!=null && tokens.length==2){
try{
long start = timeFormat.parseMillis(tokens[0]);
long end = timeFormat.parseMillis(tokens[1]);
DateTime startTime = new DateTime(start, DateTimeZone.forID(sourceTZ)).toDateTime(DateTimeZone.forID(destTZ));
DateTime endTime = new DateTime(end, DateTimeZone.forID(sourceTZ)).toDateTime(DateTimeZone.forID(destTZ));
return Arrays.asList(new LocalTime(startTime, DateTimeZone.forID(destTZ)),
new LocalTime(endTime, DateTimeZone.forID(destTZ)));
}
catch (IllegalArgumentException e){
e.printStackTrace();
}
}
};
return null;
}
}
The above code prints [13:00:00.000, 22:15:00.000]. According to this link, it's an hour off should be [12:00:00.000, 21:15:00.000]
You've only provided a time of day. What day are you interested in? That will affect the mapping to UTC. If you mean today, you should specify that explicitly. It looks like you really want to parse to a LocalTime, then construct an appropriate LocalDateTime by joining that with some appropriate LocalDate (which will depend on what you're trying to achieve).
My guess is that it's actually doing it for January 1st 1970 - at which point the UTC offset of New York was -5, not -4. You can verify that by logging startTime and endTime in full.
Also for simplicity, I'd strongly recommend calling DateTimeZone.forId just twice, at the start of the method instead of every time you need a zone.
You should also consider what you want to happen if the local date/time is ambiguous, or potentially skipped due to DST transitions. If you pick a date which doesn't include any transitions, this will never happen of course.
Related
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));
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]
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.
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);
I have this Time object:
Time myTime = java.sql.Time.valueOf("15:33:00");
How can I add 30 minutes to myTime in Java? That means the new time will be 16:03:00
java.sql.Time myTime = java.sql.Time.valueOf("15:33:00");
LocalTime localtime = myTime.toLocalTime();
localtime = localtime.plusMinutes(30);
String output = localtime.toString();
you can get localTime straight away from the java.sql.time and you can use plusMinutes in LocalTime Api to add 30 minutes. this might help you check this
Here's an easy way to do it, using java.time.LocalDateTime:
package time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalField;
/**
* Created by Michael
* Creation date 4/24/2016.
* #link
*/
public class TimeDemo {
public static void main(String[] args) {
// Three three lines do the work
LocalDateTime localDateTime = LocalDateTime.of(2016, 4, 24, 9, 10);
LocalDateTime halfHourLater = localDateTime.plusMinutes(30); // Add 30 minutes
java.sql.Time sqlDateTime = new java.sql.Time(halfHourLater.toInstant(ZoneOffset.UTC).toEpochMilli()); //
// Printout just to check
System.out.println(DateTimeFormatter.ofPattern("yyyy-MMM-dd hh:mm:ss.SSS").format(halfHourLater));
System.out.println("java.time milliseconds: " + halfHourLater.toInstant(ZoneOffset.UTC).toEpochMilli());
System.out.println("System.currentMillis : " + System.currentTimeMillis());
}
}