Quartz CronTriggerImpl computeFirstFireTime trigger timezone - timezone

As per the Quartz code in CronTriggerImpl,
public Date computeFirstFireTime(org.quartz.Calendar calendar) {
nextFireTime = getFireTimeAfter(new Date(getStartTime().getTime() - 1000l));
This ignores the timezone field and uses the system timezone even if the timezone was set on the Cron Trigger.
private transient TimeZone timeZone = null;
This causes boundary condition problems especially for DST situations. For example, say, a CronTrigger was built with America/New_York + the trigger startTime was created with the correct timezone, and then, the trigger was processed on a server in Europe, the above function takes the start time, extracts the millis and interprets them as per the server TZ. Thus, the DST window will be wrongly computed.
Is there any fix / workaround for this?

Related

What is Difference among following time zones in swift

let timeZone = NSTimeZone.system.description
let localTimeZone = TimeZone.ReferenceType.local.description
let currentTimeZone = TimeZone.current.description
let defaultTimeZone = TimeZone.ReferenceType.default.description
let autoUpdateTimezon = TimeZone.autoupdatingCurrent.description
print ("System Timezone \(timeZone)")
print ("Local Timezone \(localTimeZone)")
print ("Current Timezone \(currentTimeZone)")
print ("Default Timezone \(defaultTimeZone)")
print ("Auto updating Timezone \(autoUpdateTimezon)")
OUTPUT
System Timezone Asia/Kolkata (current)
Local Timezone Asia/Kolkata (autoupdatingCurrent)
Current Timezone Asia/Kolkata (current)
Default Timezone Asia/Kolkata (current)
Auto updating Timezone Asia/Kolkata (autoupdatingCurrent)
So, i get all the output are same so whats the difference among these timezone and which timezone we should use in which case.
Problem
I used following to code for the date conversion
static func stringToString(strDate:String, fromFormat:String, toFormat:String)->String{
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.init(abbreviation: "UTC") ?? TimeZone(identifier: "UTC") ?? TimeZone.ReferenceType.default
dateFormatter.dateFormat = fromFormat
let currentDate = dateFormatter.date(from: strDate) ?? Date()
dateFormatter.dateFormat = toFormat
dateFormatter.timeZone = TimeZone.ReferenceType.default
let currentDates = dateFormatter.string(from: currentDate)
return currentDates
}
Scene : My app is crashing in qatar if user set timezone automatically and off the 24 hours, but in india there is no crash
(TimeZone.ReferenceType.local)
I have given next build with TimeZone.ReferenceType.default and issue is solved
So, i cant understand what was the issue.
Crash Report
Old Code in which i am getting crash
Note that TimeZone.ReferenceType is basically NSTimeZone.
If you look at the docs for TimeZone and NSTimeZone you'll find out very quickly.
From the NSTimeZone:
The system class property returns the time zone currently used by the system, if known. This value is cached once the property is accessed and doesn't reflect any system time zone changes until you call the resetSystemTimeZone() method. The local class property returns an autoupdating proxy object that always returns the current time zone used by the system.
To summarise, system is cached so won't change when the user changes their time zone. You have to call resetSystemTimeZone to update it. local on the other hand automatically updates when the user changes their time zone.
The same thing is true for TimeZone:
TimeZone provides two static functions to get time zone values: current and autoupdatingCurrent. The autoupdatingCurrent time zone automatically tracks updates made by the user.
current corresponds to system and autoupdatingCurrent corresponds to local.
Local -> An object that tracks the current system time zone. Use this property when you want an object that always reflects the current system time zone. from ios 11, the local class property reflects the current system time zone, whereas previously it reflected the default time zone.
System -> The time zone currently used by the system. If you access the system class property, its value is cached by the app and doesn't update if the user subsequently changes the system time zone. In order for the system property to reflect the new time zone, you must first call the resetSystemTimeZone() method to clear the cached value.
Default -> The default time zone for the current app.If no default time zone has been set, the current system time zone is used. If the current system time zone cannot be determined, the GMT time zone is used instead.The default time zone is used by the app for date and time operations. You can set it to cause the app to run as if it were in a different time zone.
Current -> The time zone currently used by the system.
autoupdatingCurrent -> The time zone currently used by the system, automatically updating to the user’s current preference.
Source -> https://developer.apple.com/documentation/foundation/nstimezone

How can I add timezone to Esper queries?

I am using Esper & I need to filter events by their timestamp. The events come from an external source.
The challenge is that the cutoff instant is at a different timezone than the events` timestamp, e.g. the cutoff instant is at 3:30 CET (e.g. Prague time) while the timestamp field of the event is at UTC.
This poses a problem when the timezone shifts to Daylight Savings Time, because the cutoff instant needs to be modified in the query. E.g. in this case, if the cutoff instant is 3:30 CET, during winter time it would be on 2:30 UTC and during DST it would be on 1:30 UTC. It means that I have to change the query when the time shifts into and out of DST.
This is the current query:
SELECT *
FROM my_table
WHERE timestamp_field.after( timestamp.withtime(2,30,0,0) )
I would like to have a robust solution that will save me the hassle of changing the cutoff timestamp queries every few months. Can I add the timezone to the query statement itself? Is there any other solution?
It may help to add an event property to the event that represents UTC time i.e. normalize the event timestamp to UTC and use the normalized property instead.
The query could also use a variable instead of the hardcoded numbers. Another option would perhaps be changing Esper source to take in a timezone for some func.s
After struggling unsuccessfully with trying ot do it in the WHERE caluse or using a Pattern, I managed to solve the issue using a [Single-Row Function plugin][1].
I pass the plugin function the cutoff hour, timezone & event timezone and compute the cutoff hour in the event's timezone.
My query changed to:
SELECT *
FROM my_table
WHERE timestamp_field.after( timestamp.withtime(
eventTZHour(2, 'UTC', 'Europe/Prague'), 30, 0, 0) )
I added the Java implementation in a class:
public class EsperPlugins {
public int eventTZHour(int hour, String eventTZ, String cutoffTZ) {
// return tz calculations
}
}
and finally registered the plugin in esper.cfg.xml:
<esper-configuration>
<plugin-singlerow-function name="eventTZHour"
function-class="EsperPlugins"
function-method="eventTZHour"/>
</esper-configuration>
[1]: http://www.espertech.com/esper/release-5.2.0/esper-reference/html/extension.html#custom-singlerow-function from esper's docs

Timezone Offset in Angular JS and Rails

Background: I'm building an app with Angular JS as web interface and Rails API. The problem I am having is passing a date from Angular to Rails.
Issue: I have a form with a Date of Birth date field, when a user inputs his DOB say March 1st, 1985, Angular interprets it as 1985-03-01 00:00 +0800 (if you're in Hong Kong or Singapore) and sends a request to Rails. The first thing Rails does with it is to convert it to UTC, which means the datetime is now 1985-02-28 16:00 UTC. Therefore, when the date is saved to the database date column, it becomes Feb 28, 1985.
Solution for now: What I'm doing now is on Angular side, I get the Timezone offset hours and add it to the date, so instead of 1985-03-01 00:00 +0800, it is now 1985-03-01 08:00 +0800. When Rails get it, it converts to 1985-03-01 00:00 UTC and so saves the correct date to db. However, I believe this is a better alternative to tackle this issue.
Thinking about parsing just the date in Rails, yet the params[:dob] I see is already UTC by the time I get it. Would love to know if there is a better practice than my current solution. Thank you for any comment and feedback.
This problem is actually quite common, and stems from two separate but related issues:
The JavaScript Date object is misnamed. It's really a date + time object.
The JavaScript Date object always takes on the characteristics of the time zone for the environment in which it is running in.
For a date-only value like date-of-birth, the best solution to this problem is to not send a full timestamp to your server. Send just the date portion instead.
First, add 12 hours to the time, to use noon instead of midnight. This is to avoid issues with daylight saving time in time zones like Brazil, where the transition occurs right at midnight. (Otherwise, you may run into edge cases where the DOB comes out a day early.)
Then output the date portion of the value, as a string in ISO format (YYYY-MM-DD).
Example:
var dt = // whatever Date object you get from the control
dt.setHours(dt.getHours() + 12); // adjust to noon
var pad = function(n) { return (n < 10 ? '0' : '') + n; }
var dob = dt.getFullYear() + '-' + pad(dt.getMonth()+1) + '-' + pad(dt.getDate());
Another common way to do this is:
var dt = // whatever Date object you get from the control
dt.setHours(dt.getHours() + 12); // adjust to noon
dt.setMinutes(dt.getMinutes() - dt.getTimezoneOffset()); // adjust for the time zone
var dob = dt.toISOString().substring(0,10); // just get the date portion
On the Rails side of things, use a Date object instead of a DateTime. Unlike JavaScript, the Rails Date object is a date-only object - which is perfect for a date-of-birth.

get time of Different Timezone

My task: I am going to run a contest world wide at my website. A problem setter will set problems from a specific area of the world setting a time and date of starting time of the contest. I have to show that time correctly all over the world so the the contest starts at a time everywhere of the world.
My Idea : I planed to get the time from the problem setter of his time zone using server site language like php time(), & will store to database converting to timezone= zero (0). And who are going to attend the contest I'll just add hour(s) of that time zone with my database time.
Need help: I have no Idea how to convert that timestamps to timezone 'zero', even how can I get the ±hour(s) of current timezone?
Thank you...
Step 1:
Let the user choose his timezone. You could fill a dropdown with values from this site: http://php.net/manual/en/timezones.php
Step 2:
Convert the timezone to servertime
$timezone_client = new DateTimeZone('America/Denver');
$timezone_server = new DateTimeZone('Pacific/Nauru');
$datetime = new DateTime('2013-01-25 12:00:00', timezone_client);
$datetime->setTimezone($timezone_server);
echo $datetime->format('Y-m-d H:i:s');
Timezone 0 = "UTC" (sometimes called GMT)
Your system / language will have a Timezone class, which provides difference to GMT/UTC

Problem in getting DST time?

I am trying to get the time of other GMT value by using
Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone(gmt));
but how can i get the DST time at that time zone.
The TimeZone class provides a getDSTSavings() method for a specific TimeZone Object. (JavaDoc: "Returns the amount of time to be added to local standard time to get local wall clock time.")
The Calendar interface provides two getOffset() methods, which let you find out the offset from UTC. (JavaDoc: "Returns the offset of this time zone from UTC at the specified date. If Daylight Saving Time is in effect at the specified date, the offset value is adjusted with the amount of daylight saving. ")
please see this piece of code to grok the complicated ways of java time:
#Test
public void testDST() {
final TimeZone met = TimeZone.getTimeZone("MET");
Calendar gc = new GregorianCalendar(met);
final long timeInMillis = gc.getTimeInMillis();
final long gmtTime= timeInMillis-(gc.getTimeZone().getOffset(timeInMillis));
final Date gmtDate = new Date(gmtTime);
System.out.printf("%-40s: %tc\n%-40s: %tc\n%-40s: %tc\n%-40s: %d\n%-40s: %d",
"new Date() (local timezone)",new Date(),
"UTC", gmtDate ,
"now from Calendar with TC GMT+02:00",gc,
"zoneoffset",gc.get(Calendar.ZONE_OFFSET),
"dst savings",met.getDSTSavings());
}
You can also define your own SimpleTimeZone and provide custom DST rules, however, i have not found out how to get this information from the predefined TimeZones.
You should also be aware, that if TimeZone.getTimeZone(TZName) does not find the specified timezone, it does not throw an exception, but it just uses GMT, which can cause major misunderstandings.
You can find all this information (and a lot more) in javadoc for Calendar, TimeZone, Date, etc.
There are few methods available in java.util.TimeZone to get Daylight Saving Time. Please check out the BlackBerry Java Docs page.

Resources