Debug simple java code related to Calendar Date GMT - java

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.

Related

String to date format java

I have this String date="2021-04-25T18:54:18" and i should to format like that: HH:mm ,dd mmm yyyy
I tried this
String date="2021-04-25T18:54:18";
Date format= null;
try {
format = new SimpleDateFormat("HH:mm, yyyy-MM-dd'T", Locale.ENGLISH).parse(date);
holder.tvDate.setText(format.toString());
} catch (ParseException e) {
e.printStackTrace();
}
But does not work
The legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) are outdated and error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API* .
Using modern date-time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2021-04-25T18:54:18";
LocalDateTime ldt = LocalDateTime.parse(strDateTime);
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("HH:mm ,dd MMM yyyy", Locale.ENGLISH);
String output = dtfOutput.format(ldt);
System.out.println(output);
}
}
Output:
18:54 ,25 Apr 2021
Learn more about the modern date-time API from Trail: Date Time.
Using the legacy API:
You need two formatters: one for input pattern and one for output pattern. You didn't need two formatters in the case of the modern API because the modern API is based on ISO 8601 and your date-time string is already in this format.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String strDateTime = "2021-04-25T18:54:18";
SimpleDateFormat sdfInput = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
Date date = sdfInput.parse(strDateTime);
SimpleDateFormat sdfOutput = new SimpleDateFormat("HH:mm ,dd MMM yyyy", Locale.ENGLISH);
String output = sdfOutput.format(date);
System.out.println(output);
}
}
Output:
18:54 ,25 Apr 2021
* 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 are missing 1 step. SimpleDateFormat can only parse dates in the format you specify.
You are trying to parse a "yyyy-MM-dd ..." based string into the "HH:mm ..." date. This will not work.
First convert your "yyyy-MM-dd" date string into a Date.
Then, format that Date into the String you need
String input = "2021-04-25T18:54:18";
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(input);
String output = new SimpleDateFormat("HH:mm, yyyy-MM-dd", Locale.ENGLISH).format(date);

Best way to compare given date with current date without time part in a given time zone

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.

Set date and time in java.sql.Timestamp

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!

Conversion from UTC to IST returning same value in JAVA using Joda time library

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.

Convert to date

I'm trying to create number of Evenement instances and set the date for them:
for (int i=2004; i<2009; i++){
evenementen.add(new Evenement("Rock Werchter", "Rock", "Werchter", 200000,
(Date)formatter.parse(i+"/07/03")));
But I can't seem to get it to work,
Any ideas?
You may want to use Calendar to create your dates.
for (int i=2004; i<2009; i++) {
Calendar cal = Calendar.getInstance();
cal.clear();
// Calendar.JULY may be different depending on the JDK language
cal.set(i, Calendar.JULY, 3); // Alternatively, cal.set(i, 6, 3);
evenementen.add(new Evenement("Rock Werchter", "Rock", "Werchter", 200000,
cal.getTime()));
}
Note that the months are zero-based, so July is 6.
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*.
Solution using java.time, the modern API:
import java.time.LocalDate;
import java.time.Month;
public class Main {
public static void main(String[] args) {
for (int i = 2004; i < 2009; i++) {
System.out.println(LocalDate.of(i, Month.JULY, 3));
}
}
}
If you want to do it by parsing the string (the way you have posted in the question), use DateTimeFormatter.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u/M/d", Locale.ENGLISH);
for (int i = 2004; i < 2009; i++) {
LocalDate date = LocalDate.parse(i + "/07/03", dtf);
System.out.println(date);
}
}
}
Output:
2004-07-03
2005-07-03
2006-07-03
2007-07-03
2008-07-03
Learn more about java.time, 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.
Beware of the locale used for the date formatter (default can be Locale.ENGLISH is your OS is set that way, meaning the year is at the end, not at the beginning of the string)
You need to be sure to have a formatter build as (at the time of writing, 2008, Java6, as in this answer):
formatter = new SimpleDateFormat("yyyy/MM/DD");

Categories

Resources