Is MySQL time zone conversion broken?
I want to save java timestamp to DATETIME db field.
DB timezone GMT
Client timezone PST (GMT -07:00)
useTimezone = true
Client time Jul 30, 09:00:00 (GMT-07:00)
In DB I got Jul 30, 02:00:00 (GMT)
Expected in GMT - Jul 30, 16:00:00 (GMT)
During debugging I found that conversion happens here
http://www.1java2c.com/Open-Source/Java-Document/Database-JDBC-Connection-Pool/mysql/com/mysql/jdbc/TimeUtil.java.htm line 899
Is that a real issue or it is my configuration fail?
Related
According to https://developers.google.com/gmail/api/guides/filtering, if you search for a date, the PST timezone is used.
I have an email with:
Date: Tue, 27 Jul 2021 06:07:49 GMT (06:07 AM)
If you convert this to the PST timezone, it should be:
Date: Mon, 26 Jul 2021 23:07:49 PST (11:07 PM)
Now when i use the query
after:2021/07/27
the email is found but shouldn't be according to the definition (also when i search directly on gmail.com).
For the query
before:2021/07/27
nothing is returned.
I didn't find a description yet on how to correctly search by a date and which timezones are really applied.
I'm using google-api-services-gmail-v1-rev110-1.25.0.jar.
Additional info:
String account = "myemail#gmail.com";
List<String> labelIds = new ArrayList<>();
labelIds.add("Label_mylabelid");
String query = "after:2021/07/27";
List<Message> timeZoneMsgs = gmail.users().messages().list(account).setQ(query).setLabelIds(labelIds).execute().getMessages();
I ran another test: I scheduled some emails to be sent between 11:30pm and 01:00am on the next day.
Here are the date headers (directly out of the payload) of the messages:
Scheduled mail 1
Date: Fri, 24 Dec 2021 23:30:00 +0100
Scheduled mail 2
Date: Fri, 24 Dec 2021 23:45:00 +0100
Scheduled mail 3
Date: Sat, 25 Dec 2021 00:00:00 +0100
Scheduled mail 4
Date: Sat, 25 Dec 2021 00:15:00 +0100
Scheduled mail 5
Date: Sat, 25 Dec 2021 00:30:00 +0100
Scheduled mail 6
Date: Sat, 25 Dec 2021 00:45:00 +0100
Scheduled mail 7
Date: Sat, 25 Dec 2021 01:00:00 +0100
If I search with
after:2021/12/25
directly on gmail.com - i get the messages 3 to 7 and if i search with
before:2021/12/25
I get 1 and 2, which is both correct.
BUT when I do the same with the java call, I only get message 7 (1am) for "after:2021/12/25" and messages 1-6 for "before:2021/12/25".
Another example:
I also tried searching with the epoch time in UTC:
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.clear();
calendar.set(2021, Calendar.DECEMBER, 25);
long secondsSinceEpoch = calendar.getTimeInMillis() / 1000L; // 1640390400
Here, I get the same result for direct gmail.com search and java search: Message 7 (1pm) for "after:1640390400" and 1-6 for "before:1640390400".
If I try this for PST (1640419200), I get no messages for "after:1640419200" and all of them for "before:1640419200".
As the documentation states:
To specify accurate dates for other timezones pass the value in seconds instead.
This is a Java sample code, is tested and working .For the example I get all the messages from yesterday 23:00 to today 13:00. Tip: You can use me as a keyword to your email account:
long startTimeEpoch = LocalDateTime.parse("2021-12-27T23:00",
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")).toEpochSecond(ZoneOffset.UTC);
long endTimeEpoch = LocalDateTime.parse("2021-12-28T13:00",
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm")).toEpochSecond(ZoneOffset.UTC);
String query = String.format("after:%s before:%s", startTimeEpoch, endTimeEpoch);
String account = "me";
System.out.println(query);
List < String > labelIds = new ArrayList < > ();
labelIds.add("Label_mylabelid");
List < Message > timeZoneMsgs = service.users().messages().list(account)
.setQ(query)
.execute()
.getMessages();
System.out.println(timeZoneMsgs);
Documentation:
Gmail API Javadoc documentation
LocalDateTime
DateTimeFormatter
I have application written in spring that allows user to filter data by date.
Filters model:
data class FilterCommand(
#field:DateTimeFormat(pattern = "dd/MM/yyyy") val dateFrom: Date?,
#field:DateTimeFormat(pattern = "dd/MM/yyyy") val dateTo: Date?,
val author: String?,
val state: String?
)
Everything works fine, except when user chooses 07/06/2019 in UI, I get exactly same value in Spring in current timezone.
Is it possible to tell spring to treat this incoming data as UTC?
Or to convert it somehow on model level?
Date I receive: Fri Jun 07 00:00:00 CEST 2019
Date I would like to get: Fri Jun 07 00:00:00 UTC 2019
You can configure the timezone directly in the JVM, so if you set it to UTC, all dates will be on UTC.
Im trying to get emails of a certain date from an inbox in outlook using IMAP, but im getting emails from dates that dont correspond to the date im using for my search, my code is the following:
SimpleDateFormat df1 = new SimpleDateFormat( "MM/dd/yy" );
String dt="10/02/18";
java.util.Date dDate = df1.parse(dt);
/*
Connection code to the email goes here
*/
SearchTerm st = new ReceivedDateTerm(ComparisonTerm.EQ,dDate);
IMAPFolder inbox = (IMAPFolder) store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
Message[] messages = inbox.search(st);
int total = messages.length;
/* RESULTS */
println("\nTotal_Email = " + messages.length);
for (int index = 0; index < total; index++) {
Date date=message.getReceivedDate();
System.out.println("DATE RECEIVED="+date);
}
Im getting the following result when I use the date "10/01/18"
Total_Email = 5
DATE RECEIVED=Mon Oct 01 17:45:44 COT 2018
DATE RECEIVED=Mon Oct 01 16:43:27 COT 2018
DATE RECEIVED=Mon Oct 01 16:17:11 COT 2018
DATE RECEIVED=Mon Oct 01 15:37:38 COT 2018
DATE RECEIVED=Mon Oct 01 14:53:48 COT 2018
And then Im getting the following result when I use the date "10/02/18"
Total_Email = 6
DATE RECEIVED=Tue Oct 02 08:09:53 COT 2018
DATE RECEIVED=Mon Oct 01 23:21:34 COT 2018
DATE RECEIVED=Mon Oct 01 22:37:22 COT 2018
DATE RECEIVED=Mon Oct 01 21:33:37 COT 2018
DATE RECEIVED=Mon Oct 01 20:21:20 COT 2018
DATE RECEIVED=Mon Oct 01 19:11:50 COT 2018
My guess is that it has to do with my timezone, I live in Colombia and my timezone is GMT-5, Is there any way to fix and get the correct results ?
No, IMAP is not timezone aware, and it is server specific what timezone it computes and reports the results in. You may need to request more than you need and do client side filtering.
Most of the large multinational servers use UTC for convenience, so you'd have to fetch the two days overlapping the period you're interested in.
Initially I had quite simple test:
#Test
public void testMe() {
System.out.println("Records in H2 db:");
List<DateRangeBean> all = dateRangeServiceImpl.findAll();
all.forEach(x -> System.out.println(x.getDateTo()));
Clock.system(ZoneId.of("UTC"));
ZonedDateTime currentDate = ZonedDateTime.of(2016, 8, 9, 0, 0, 0, 0, clock.getZone());
Date currentDate_date = Date.from(currentDate.toInstant());
System.out.println("Current Date is: " + currentDate_date);
List<DateRangeBean> result = new ArrayList<>();
dateRangeServiceImpl.findGreaterDateTo(currentDate_date).iterator().forEachRemaining(result::add);
result.forEach(x -> System.out.println(x.getDateTo()));
assertEquals(result.size(), 2);
}
that always was executed on PC with default TimeZone UTC and with the following output:
Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
where:
dateRangeServiceImpl.findAll() implemented as:
public List<DateRangeBean> findAll (){
List<DateRangeBean> result = new ArrayList<>();
dateRangeRepository.findAll().iterator().forEachRemaining(result::add);
return result;
}
dateRangeServiceImpl.findGreatedDateTo(Date date):
public List<DateRangeBean> test (Date currentDate){
List<DateRangeBean> result = new ArrayList<>();
dateRangeRepository.findGreatedDateTo(currentDate).iterator().forEachRemaining(result::add);
return result;
}
and dateRangeRepository - is pure interface as part of Spring Data
public interface DateRangeRepository extends PagingAndSortingRepository<DateRangeBean, Long> {
#Query("from DateRangeBean drb where (drb.dateTo >= :currentDate)")
List<DateRangeBean> findGreatedDateTo(#Param("currentDate") Date currentDate);
}
and DateRangeBean:
#Entity
public class DateRangeBean implements java.io.Serializable {
#Temporal(TemporalType.DATE)
#Column(name = "date_To", length = 10)
private Date dateTo;
.....................
public Date getDateTo() {
return new Date(this.dateTo.getTime());
}
public void setDateTo(Date dateTo) {
this.dateTo = new Date(dateTo.getTime());
}
}
Today I have tried to run this test on PC with Time Zone: UTC -07:00 and test failed with the following output:
Records in H2 db:
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Current Date is: Mon Aug 08 17:00:00 MST 2016
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
java.lang.AssertionError: expected [2] but found [3]
Expected :2
Actual :3
Okey, maybe, it is reasonable: we defined currentDate variable Aug 9 UTC TZ, but on the next step we re-converted currentDate to currentDate_date in MST TZ and as result it is Aug 8.
BUT:
Q1:
based on our #Query: drb.DateTo >= :currentDate
in current case: Mon Aug 08 00:00:00 MST 2016 >= Mon Aug 08 17:00:00 MST 2016 - this statement is incorrect!
Assume, that Spring Data compares only Day, Month, Year and trims Time segment.
Is it correct??
Q2:
I tried to fix the test putting the timezone directly in the test:
public void testMe() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
..............
}
But I still getting failed result:
Records in H2 db:
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
java.lang.AssertionError: expected [2] but found [3]
And at the moment I can't understand how is it possible:
Mon Aug 08 07:00:00 UTC 2016 >= Tue Aug 09 00:00:00 UTC 2016 ?
Q3:
I tried to specify TZ as part of Spring Context:
<bean id="defaultZoneInfo" class="sun.util.calendar.ZoneInfo" factory-method="getTimeZone">
<constructor-arg type="java.lang.String" value="UTC"/>
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="java.util.TimeZone.setDefault"/>
<property name="arguments">
<list>
<ref bean="defaultZoneInfo"/>
</list>
</property>
</bean>
but the result was the same as with Q2.
Q4:
Specify TZ in static block:
static {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}
and test - passed!
Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
So, can someone explain why specifying default TZ in Spring Context xml file and directly in test method didn't fix problem?
And only specifying TZ via static block solved the problem?
I think it may be your database problem not your application
for example Oracle database not accept connection from client after changing Client location in control panel.
I am working on project using GWT java GAE. In my project i have used cron job.
when i schedule its time like every 5 minutes, every 2 minutes in cron.xml then its working fine i will getting my ouput. but when i schedule it time like every 24 hours or every day 21:00 then cron job executed but its throw error :-
E 2015-11-03 20:18:10.825
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding Day03-Nov-2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date -30 Days DateSat Oct 03 23:59:59 UTC 2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today DateMon Nov 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.832
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date After Setting the Time Mon Nov 02 23:59:59 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding Day03-Nov-2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date +30 Days DateWed Dec 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date Before Adding One DayMon Nov 02 18:30:00 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Today Date +30 Days DateThu Dec 03 18:29:29 UTC 2015
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: In Contract List
E 2015-11-03 20:18:10.833
com.slicktechnologies.server.cronjobimpl.ContractRenewalCronJobImpl ContractRenewallist: Date After Adding One DateMon Nov 02 23:59:59 UTC 2015
I 2015-11-03 20:18:11.146
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
Any help
Thanks in advance
The message about starting a new instance is not an error, it's just an informational message, expected when app instances are dynamically created (note the i marking):
GAE automatically stops dynamic instances after a period of inactivity (of at least 15 minutes) and start new instances on demand. Your app instance is not idle long enough when the job is scheduled every 2 or 5 minutes because of the cron job itself, but it may be when running the job daily.
More details in here.
You can see the message even when running the job every 2 or 5 minutes if, for example, you stop your instance manually.