Please tell me how to set the date (current date minus one day) and time equal to 19:00:00 using such a construction?
new java.sql.Timestamp(java.util.Calendar.getInstance.getTime().getTime())
LocalDateTime don't use.
I recommend you do it using the java.time (the modern date-time API).
Solution, purely using the modern API:
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
OffsetDateTime odt = ZonedDateTime.now(ZoneId.systemDefault())
.minusDays(1)
.with(LocalTime.of(19, 0))
.toOffsetDateTime();
System.out.println(odt);
}
}
Output:
2020-12-24T19:00Z
You can use the OffsetDateTime in your JDBC code as follows:
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
However, if you still want to use java.sql.Timestamp, you can use ZonedDateTime with the applicable timezone to get the required date-time and then convert it into Instant from which you can get Epoch milliseconds. You can Finally use the Epoch milliseconds to construct an instance of java.sql.Timestamp.
import java.sql.Timestamp;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault())
.minusDays(1)
.with(LocalTime.of(19, 0));
Timestamp timestamp = new Timestamp(zdt.toInstant().toEpochMilli());
System.out.println(timestamp);
}
}
Output:
2020-12-24 19:00:00.0
Notes:
I have used ZoneId.systemDefault() which uses the JVM's timezone. Change it to applicable timezone e.g. ZoneId.of("Europe/London").
Instant belongs to the modern date-time API. Learn about the modern date-time API from Trail: Date Time.
For whatsoever reason if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.
Solution, purely using the legacy API:
import java.sql.Timestamp;
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, -1);
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Timestamp timestamp = new Timestamp(calendar.getTimeInMillis());
System.out.println(timestamp);
}
}
Output:
2020-12-24 19:00:00.0
This is my code
Set date to yesterday with Calendar.add(Calendar.DAY_OF_YEAR, -1)
Compare hour with Calendar.get(Calendar.HOUR_OF_DAY)
getHour of java.sql.Timestamp is Deprecated.
replaced by Calendar.get(Calendar.HOUR_OF_DAY).
import java.sql.Timestamp;
import java.util.Calendar;
Calendar calendar = Calendar.getInstance(); // 2020-12-25 19:42:57.739
calendar.add(Calendar.DAY_OF_YEAR, -1);
Timestamp timestamp = new Timestamp(calendar.getTimeInMillis());
System.out.println(timestamp); // 2020-12-24 19:42:57.739
System.out.println(19 == calendar.get(Calendar.HOUR_OF_DAY)); // true
Bye!
Related
I am taking input in the java.time.LocalDateTime format as I need hours/minutes.
input : 2020-04-19T01:03:50
To interact with oracle DB from jpaRepostory, I am using
import org.joda.time.DateTime;
List<String> findApps(#Param("lastModifiedDate") DateTime lastModifiedDate);
For conversion from LocalDate to dateTime I am using this way
DateTime.parse(startDate.toString(), DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss"))
But I am getting this result and unable to fetch any records.
2020-04-19T01:03:50.000+05:30
Can anyone help me.
PS: Thank you in advance.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = LocalDateTime.parse("2020-04-19T01:03:50");
OffsetDateTime odtIndia = ldt.atZone(ZoneId.of("Asia/Kolkata")).toOffsetDateTime();
System.out.println(odtIndia);
OffsetDateTime odtUtc = odtIndia.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odtUtc);
}
}
Output:
2020-04-19T01:03:50+05:30
2020-04-18T19:33:50Z
ONLINE DEMO
The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
Learn more about the modern Date-Time API from Trail: Date Time.
Using Joda API:
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = new LocalDateTime("2020-04-19T01:03:50");
DateTime dtIndia = ldt.toDateTime(DateTimeZone.forID("Asia/Kolkata"));
System.out.println(dtIndia);
DateTime dtUtc = dtIndia.toDateTime(DateTimeZone.UTC);
System.out.println(dtUtc);
}
}
Output:
2020-04-19T01:03:50.000+05:30
2020-04-18T19:33:50.000Z
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.
You can try something like this
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Joda {
public static void main(String[] args) {
DateTime startDate = new DateTime();
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss");
String formatted = dtf.print(startDate); //prints 2021-06-26T17:32:50
System.out.println(formatted);
DateTime parsed = DateTime.parse(formatted, DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss"));
}
}
My requirement is to compare a given date in a particular format in a given timezone to the current date in the same time zone.
Also while comparing I have to ignore the timezone.
And the comparison result should be:
0 or 1 or -1
One way I have tried is
Set the required timezone
Get the current date using "new Date()" format it using "yyyy-MM-dd" and then parse it again to get the date object
Use the same formatter for supplied date string to be compared
Then compare both dates using compareTo which gives the desired result
public void compareDate(){
TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
Date todayDate = dateFormatter.parse(dateFormatter.format(new Date()));
Date date = dateFormatter.parse("2021-02-28");
System.out.println(todayDate.compareTo(date));
}
But the above looks inefficient to me.
Other way could be to get both the dates like below and then compare?
public static Date getDateWithoutTimeUsingCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
Can someone please suggest a better alternative?
Just one thing, timezone and comparing without time has to be there.
The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.*
Demo using java.time API (modern date-time API):
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Tests
try {
System.out.println(compareWith("2021-02-28", "yyyy-MM-dd", "Asia/Calcutta"));
System.out.println(compareWith("2021/03/03", "yyyy/MM/dd", "Asia/Calcutta"));
} catch (DateTimeException e) {
System.out.println("Date string parsing error occured.");
}
}
static int compareWith(String strDate, String format, String timezone) throws DateTimeException {
ZoneId zoneId = ZoneId.of(timezone);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(format, Locale.ENGLISH);
ZonedDateTime today = ZonedDateTime.now(zoneId).with(LocalTime.MIDNIGHT);
ZonedDateTime date = LocalDate.parse(strDate, dtf).atStartOfDay(zoneId);
return today.compareTo(date);
}
}
Output:
1
-1
Learn more about the modern date-time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.
There is an XMLGregorianCalendar object that contains the value "2021-01-18T18:43:26.884Z" (This is its output in toString()). When I try to serialize this date with Jackson, I get a date 3 hours later in the output:
XMLGregorianCalendar date = ...;
ObjectMapper mapper = new ObjectMapper();
String out = mapper.writeValueAsString(obj); // Output: 1610995406884 (Converted to Date: Mon Jan 18 21:43:26 MSK 2021)
How can I solve this problem?
There is no problem at all.
The time "2021-01-18T18:43:26.884Z" in your XMLGregorianCalendar
is 18:43 in the GMT timezone (Greenwich mean time, London) or UTC+0 (because of the trailing Z).
In the other hand you have a Date object with the string representation
"Mon Jan 18 21:43:26 MSK 2021",
which is 21:43 in the MSK timezone (Moscow Standard Time) or UTC+3.
The Date class chose this timezone for formatting the output
simply because your computer is located near Moscow.
So both are actually the same point in time,
just only stringified for two different timezones.
java.util.Date represents the number of milliseconds since the epoch
The java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat and obtain the formatted string from it.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(1610995406884L);
Date date = calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(date));
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
System.out.println(sdf.format(date));
}
}
Output:
2021-01-18T18:43:26.884
2021-01-18T21:43:26.884
Note that the date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
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 and How to use ThreeTenABP in Android Project.
Convert the legacy, java.util.Date to the modern java.time.Instant using java.util.Date#toInstant:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(1610995406884L);
Date date = calendar.getTime();
Instant instant = date.toInstant();
System.out.println(instant);
// You can convert Instant to other types e.g.
ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/Moscow"));
// Print default format i.e. the value of zdt#toString
System.out.println(zdt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss'['z']'");
String formatted = dtf.format(zdt);
System.out.println(formatted);
}
}
Output:
2021-01-18T18:43:26.884Z
2021-01-18T21:43:26.884+03:00[Europe/Moscow]
2021-01-18T21:43:26[MSK]
The Z stands for Zulu and represents UTC (or GMT).
I need to convert TimeZone in my project from UTC to IST and vice versa. For that purpose I am using Joda time jar in my project. But the problem occurs when I try to convert the string from UTC to IST, I am getting the same value instead of getting converted IST value. Kindly please mentor me in which part of code I am completely stuck up. My code is as follows:
public class JodaDemo {
public static final String DATE_PATTERN_SERVICE = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_PATTERN_SERVICE_NO_SECONDS = "yyyy-MM-dd HH:mm";
public static void main(String[] args) {
getDateFromUTCtoIST("2015-08-23 10:34:40");
}
private static void getDateFromUTCtoIST(String dateTime) {
DateTimeFormatter dtf = DateTimeFormat.forPattern(DATE_PATTERN_SERVICE);
DateTime jodatime = dtf.parseDateTime(dateTime);
DateTimeZone indianTimeZone = DateTimeZone.forID("Asia/Kolkata");
DateTime indianTime = jodatime.withZone(indianTimeZone);
System.out.println(indianTime);
}
OUTPUT:
2015-08-23T10:34:40.000+05:30
Expected output:
Converted TimeZone (+5:30 output) like in yyyy-MM-dd HH:mm:ss format
There are two problems here. Firstly, when you're parsing the value you're not specifying the time zone - so it's using your local time zone. Secondly, you're not using any formatter for the result - you're just calling DateTime.toString(), implicitly.
The simplest approach is actually to create two formatters for the same pattern, one in UTC and one in the relevant time zone - then you don't need to manually convert at all, as the formatter can do it for you:
import java.util.*;
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static final String DATE_PATTERN_SERVICE = "yyyy-MM-dd HH:mm:ss";
public static void main(String[] args) {
DateTimeFormatter utcFormatter = DateTimeFormat
.forPattern(DATE_PATTERN_SERVICE)
.withLocale(Locale.US)
.withZoneUTC();
DateTimeZone indianZone = DateTimeZone.forID("Asia/Kolkata");
DateTimeFormatter indianZoneFormatter = utcFormatter.withZone(indianZone);
String utcText = "2015-08-23 10:34:40";
DateTime parsed = utcFormatter.parseDateTime(utcText);
String indianText = indianZoneFormatter.print(parsed);
System.out.println(indianText); // 2015-08-23 16:04:40
}
}
java.time
Quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2015-08-23 10:34:40";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, parser);
ZonedDateTime zdtUtc = ldt.atZone(ZoneId.of("Etc/UTC"));
ZonedDateTime zdtIndia = zdtUtc.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
OffsetDateTime odt = zdtIndia.toOffsetDateTime();
System.out.println(odt);
}
}
Output:
2015-08-23T16:04:40+05:30[Asia/Kolkata]
2015-08-23T16:04:40+05:30
ONLINE DEMO
Some important notes:
If you are going to deal with JDBC, check this answer and this answer to learn how to use java.time API with JDBC.
For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(odt.toInstant());
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Test {
public static void main(String[] args) throws ParseException {
Calendar dateFromNet = strToCal("11-MAR-2004", "dd-MMM-yyyy");
Calendar IEndTime = strToCal("20-05-2004", "dd-mm-yyyy");
if (dateFromNet.after(IEndTime) ) {
System.out.println(dateFromNet);
System.out.println(IEndTime);
System.out.println("not true: 11-MAR-2004(11-3-2004) > 20-05-2004 ");
}
}
private static Calendar strToCal(String date, String format) throws ParseException {
SimpleDateFormat input = new SimpleDateFormat(format);
input.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d = (Date) input.parse(date);
Calendar c = Calendar.getInstance();
c.setTime(d);
return c;
}
}
This test shows
dateFromNet.after(IEndTime) == true
i.e. 11-03-2004 is after 20-05-2004
What have I done wrong?
Calendar IEndTime = strToCal("20-05-2004", "dd-mm-yyyy");
mm is for milliseconds; make those capitol M, like this:
Calendar IEndTime = strToCal("20-05-2004", "dd-MM-yyyy");
The letter, m and M have different meanings as shown in the following table:
Letter
Date or Time Component
Presentation
Examples
m
Minute in hour
Number
30
M
Month in year
Month
July; Jul; 07
So, the root cause of the problem is using m instead of M in the pattern, dd-mm-yyyy.
java.time
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Demo of the modern API:
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
ZonedDateTime dateFromNet = strToZdt("11-MAR-2004", "d-MMM-u");
ZonedDateTime IEndTime = strToZdt("20-05-2004", "d-M-u");
if (dateFromNet.isAfter(IEndTime)) {
System.out.println("11-MAR-2004 > 20-05-2004");
} else if (dateFromNet.isBefore(IEndTime)) {
System.out.println("11-MAR-2004 < 20-05-2004");
} else {
System.out.println("11-MAR-2004 = 20-05-2004");
}
}
private static ZonedDateTime strToZdt(String date, String format) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern(format)
.toFormatter(Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(date, dtf);
return localDate.atStartOfDay(ZoneId.of("Etc/UTC"));
}
}
Output:
11-MAR-2004 < 20-05-2004
If at all you need an object of java.util.Calendar from this object of ZonedDateTime, you can do so as follows:
Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(dateFromNet.toInstant()));
Learn more about the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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 and How to use ThreeTenABP in Android Project.