GMAIL API - Date search (timezone unclear) - java

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

Related

Spring - Treat incoming date as UTC

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.

Javamail IMAP - Searching mail by date returning wrong results

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.

Java, failed test after changing Time zone on PC

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.

ews-java-api: Error on item update: At least one recipient isn't valid

I am working on a tool which uses ews-java-api to create, update and delete calendar items in Outlook agenda. It has been working fine, but now sometimes when it tries to update some calendar item, I get following error:
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceResponseException: At least one recipient isn't valid., A message can't be sent because it contains no recipients.
at microsoft.exchange.webservices.data.core.response.ServiceResponse.internalThrowIfNecessary(ServiceResponse.java:278)
at microsoft.exchange.webservices.data.core.response.ServiceResponse.throwIfNecessary(ServiceResponse.java:267)
at microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:165)
at microsoft.exchange.webservices.data.core.ExchangeService.internalUpdateItems(ExchangeService.java:691)
at microsoft.exchange.webservices.data.core.ExchangeService.updateItem(ExchangeService.java:762)
at microsoft.exchange.webservices.data.core.service.item.Item.internalUpdate(Item.java:279)
at microsoft.exchange.webservices.data.core.service.item.Item.update(Item.java:400)
at be.vrt.quintiqexchange.main.QuintiqAdapter.insertUpdateCalendarItems(QuintiqAdapter.java:879)
at be.vrt.quintiqexchange.main.QuintiqAdapter.updateCalendarItems(QuintiqAdapter.java:796)
at be.vrt.quintiqexchange.main.QuintiqAdapter.run(QuintiqAdapter.java:286)
at java.lang.Thread.run(Thread.java:745)
Recently all the exchange accounts have been migrated from local Outlook servers to Office365 cloud servers. Maybe this has something to do with it? Or anybody have any idea on what is going wrong?
Following code is to perform the update for an item:
Item it = alitems.get(i);
...
it.update(ConflictResolutionMode.AlwaysOverwrite);
Following is the url being used to access office365 ews:
exchangewebservice = https://outlook.office365.com/EWS/Exchange.asmx
Thanks in advance
Edit: I use ews-java-api version 2.0
Edit: Here you can see that the error occurs on one line and than the next line, with the same recipient it doesn't occur...
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceResponseException: At least one recipient isn't valid., A message can't be sent because it contains no recipients.
at microsoft.exchange.webservices.data.core.response.ServiceResponse.internalThrowIfNecessary(ServiceResponse.java:278)
at microsoft.exchange.webservices.data.core.response.ServiceResponse.throwIfNecessary(ServiceResponse.java:267)
at microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:165)
at microsoft.exchange.webservices.data.core.ExchangeService.internalUpdateItems(ExchangeService.java:691)
at microsoft.exchange.webservices.data.core.ExchangeService.updateItem(ExchangeService.java:762)
at microsoft.exchange.webservices.data.core.service.item.Item.internalUpdate(Item.java:279)
at microsoft.exchange.webservices.data.core.service.item.Item.update(Item.java:400)
at be.vrt.quintiqexchange.main.QuintiqAdapter.insertUpdateCalendarItems(QuintiqAdapter.java:880)
at be.vrt.quintiqexchange.main.QuintiqAdapter.updateCalendarItems(QuintiqAdapter.java:703)
at be.vrt.quintiqexchange.main.QuintiqAdapter.run(QuintiqAdapter.java:283)
at java.lang.Thread.run(Thread.java:745)
WARN be.vrt.quintiqexchange.main.QuintiqAdapter - At least one recipient isn't valid., A message can't be sent because it contains no recipients.by UPDATE for subject: on Thu Jun 23 14:00:00 CEST 2016 Thu Jun 23 19:00:00 CEST 2016 of user name.lastname#domain.com
INFO be.vrt.quintiqexchange.main.QuintiqAdapter - Appointment updated for subject: NIET DAG on Fri Aug 05 10:00:00 CEST 2016 Fri Aug 05 18:00:00 CEST 2016 of user name.lastname#domain.com
INFO be.vrt.quintiqexchange.main.QuintiqAdapter - Appointment updated for subject: PROEF st5 on Mon Aug 22 10:00:00 CEST 2016 Mon Aug 22 20:30:00 CEST 2016 of user name.lastname#domain.com
This means that the recipient isn't really the issue, I guess...
p.s. I replaced the original mailaddress but believe me, it's a correct mailadres :)
In my case, if the address is not properly trimmed and has any whitespace characters at all, EWS vomits this exception up.

MySQL time zone conversion issue

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?

Categories

Resources