Changing a time - datetime

I have a scheduling system on which several people schedule activities, by adding to a Google Sheet event_id, start_date, finish_date and start_time (HH:mm). This goes through various validity checks, including matching start_time to a list of valid start times on another sheet.
This works. But some of these activities are between midnight and 6am, and are therefore scheduled as belonging to the day before and sorted to the end of the daily list, not the beginning.
I do this by, for example, entering 01:30 as 25:30, which then displays as 01:30 and stores as Sunday Dec 31 1899 01:30:00, and all works as it should.
But when other people enter start times, they will often forget the instructions and enter the start time as 01:30, which does not match the validation and further processing. What I am trying to achieve is an automatic change to such entries, such that one day is added and the system stores Sunday Dec 31 1899 01:30:00, which matches the validation.
But it doesn't. Entering 25:30 by hand works perfectly, but entering 01:30 and then passing it to:
if (stime.getDay() == 6 && shr < daystart){
stime.setDate(31);
osheet.getRange(activerow,7).setValue(stime);
appears to work, but then does not match the validation grid.
I have tried numerous ways to add the 24 hours, such as
stime.setDate(stime.getDate()+1);
but all with the same outcome. A manual input of 25:30 checked for equality against the appropriate cell in the validation grid returns TRUE; any computational method returns FALSE on the same test.
I am clearly doing something stupid, but what?
Thank you for reading this.

It's always the way. Give up, ask for help, and then the answer occurs to you. There is a calculation error somewhere; the calculated value differs from the manual input from the 11th decimal place onwards. So, surrounding both parameters in the validation check with a =ROUND(stime,8) etc, will fix it. Sorry to have wasted your time. But I'll leave this here in case anybody else has a similar problem.

Related

Timezone and date conversion problems

I have a simple system, which on node creation form, allows user to select start and end dates along with hours and minutes:
The problem is that the date gets messed up somewhere in the middle, or I don't know how to convert it.
In the database, two values gets saved as follows:
start: "2019-08-01T14:00:00.000Z"
end: "2019-08-01T16:00:00.000Z"
Seems correct, as in the datepicker I chose 2pm and 4pm. Then, using momentjs and react-big-calendar, I try to put that event into calendar. It seems that it puts +3 hours every time. I assume, it is because it saves it in UTC format, and I live in Eastern Europe, which is +3 hours from UTC.
What is strange, is that I already get back time converted to my own when I make a request to the database:
Thu Aug 01 2019 17:00:00 GMT+0300 (Eastern European Summer Time)
Could someone help me out? I would expect to have the same hours returned and displayed, as I save them, meaning if I select 2pm, it should be 2pm. I think the solution here would be to ignore timezones, and always display everything in UTC? But how to do that? I have access to momentjs if that helps. I tried something like this:
moment.utc(event.start);
But it still returns the same value, which is:
Thu Aug 01 2019 17:00:00 GMT+0300 (Eastern European Summer Time)
When you setup React-Big-Calendar, you define a localizer. By default, the calendar will display in the local timezone of the browser the user is using. Any and all dates given to the calendar will be converted to that local timezone. If your dates, coming from the db, use an offset of +5, but you're sitting in +3, it will automatically convert those times to display +3 (part of the beauty of UTC).
This is where it can get tricky. Say I want to get all values from my db between Sep 19th and Sep 21st. I have to remember those offsets when requesting data from the system. I could use moment and say moment('2019-09-19').startOf('day'), and it would give me 2019-09-19T00:00:00Z, but this isn't exactly correct for me, as I'm at an offset of -5, which means I actually needed 2019-09-18T19:00:00Z to get the start of my day. The same holds true for my end datetime, where I would say moment('2019-09-21').endOf('day') and it would give me 2019-09-21T23:59:59Z, when I would need 2019-09-21T18:59:59Z.
Now, I'm not positive of this (you'll have to do some testing), but if you use moment-timezone instead of moment it may handle all of this for you. You'll have to play around to know for sure.
FINAL EDIT: I worked out timezone handling with moment-timezone as my localizer. I put the entire thing in a GitHub project, as well as creating a CodeSandbox where people can play with it.
TRULY FINAL EDIT: The (0.36.0) latest version of RBC has full timezone support now, when using either the momentLocalizer or the new luxonLocalizer. Doc site isn't up to date yet, but if you run the 'examples' locally you'll find all the info.

When date only is required to save, Converting it to UTC and then to local may behave differently in different time zones

I have a date field at front end. And I am saving it from a time zone say 19/04/2018 and I am on +8. When I load it on local datetime.ToLocalTime() works perfectly in +8 offset and it will show 19/04/2018 but a person sitting in +7 would get in 18/04/2018 23:00 and hence it will show 18/04/2018. How to handle this case.
In general: you should not convert date only to UTC, so you should keep it as local date.
But it really depend on the use of data.
If you are using for some synchronization (all invoices until a fix point), a time with timezone is good, but in such case, also hours and minutes should be included.
If you care about the date written in an invoice, you may not transform date to UTC (so keep local date). If you aggregate invoices, you may wait until the day is passed on all timezone (and people filled all invoices into the system).
When people are looking into the data, what they expect? (case #1 or case #2). Then evaluate what kind of data you need. In the first case, you should add also (at minimum) the hours and minute (timezones never have seconds).
In general, if you have only a date, you are mostly on second case.

Reversal of PeopleSoft Time and Labor Stat Holiday Payout causes summing errors

(Note that my knowledge of Time and Labor processing is limited. This is just something that was done previously by someone else that needs fixing, not a general T&L implementation)
Background
Business has a Stat Holiday Bank policy, where employees who are not scheduled to work on holidays get a 7.5 hour bank credit. Expiry is within 90 days if not taken and results in a payout.
The initial implementation of this T&L Rule did not correctly determine cases where a Banked Stat Holiday due for expiration had already been taken and, as a result, often paid out at the wrong dates.
Approach for Rule reimplementation.
The Banked and Taken event need to be matched up, rather than just applying 90 day aging rules. #1Banked, #2Banked, #3Taken really means that the #1Banked is cancelled out by the #3Taken, so that only #2Banked is up for expiration. In this context, a Payout really is a form of Taken.
So the rule was rewritten as follows:
Load all Record.TL_COMPLEAV_TBL rows since the last 0-balance date, and up the T&L Batch's POI_START_DT, into a work table.
Add current Batch incoming TL_IPT1 rows for Taken into work table.
Rank events by age i.e. Banked #1, Banked #2, Banked #3. Taken #1, Taken #2.
Cross-out Banked events that have a matching Taken.
What works
So far, so good. I can generate Payouts at appropriate times, when I examine the actual dates that the employees earned and took banked time off. I checked the TL_IPT1 rows that the original implementation was emitting and my own contents match on all fields, except for the date of payout.
What doesn't work.
When we re-process Time and Labor via Process.TL_TIMEADMIN, the new rule does not generate payouts that had been done incorrectly. It in fact, does not send anything to TL_IPT1.
Time and Labor however picks up that the payout isn't happening and generates a reversal. -7.5hrs to Payout, same date as original payout.
So far, so good.
However, the next time that Process.TL_TIMEADMIN is run, if I have a banked time earned event, then things go wrong.
Section.TL_COMPTIME.DA000 kicks in, does some calculations, calls DD000 and instead of say adding 7.5 earned hours to a banked 15, giving 22.5 it will set the bank to 0 hours.
Oddly enough, I had expressed surprise that the vanilla T&L implementation supports the notion of expiry and aging in TL_COMPLEAV_TBL but then, according to the business owner, does nothing with it. Section.TL_COMPTIME.DA000, which I haven't reviewed yet in detail, seems to be intended for keeping track of Taken and Earned so it almost looks to me as it then decides to do aging that the custom rule has already done.
By doing nothing when there is nothing to do, am I taking the wrong approach to support reversals? Should I instead insert a row into TL_IPT1 with TL_QUANTITY=0 for that day, when I see that there was a previous incorrect payout?
I am fairly confident that my payout calculations are correct - they are the same as the previous ones, only the dates differ. But I don't know how to handle reversals.

How can I use the occurrences to calculate the end date of a recurring event in eas

Can anyone tell me the best way of calculating the end date of a recurring event from the number of occurrences and the pattern in which the event occurs.
For example:
I have an event which has start date as 10/07/2014 (Tuesday) and occurs every week on Tuesday. This event will end after 10 occurrences (say). So, the my method should return me the end date as : 12/09/2014
The method should also consider more complex situations like suppose if the event occurs yearly on first Monday of October and has total 10 occurrences.
(This isn't an answer which gives you a complete solution by any means, but hopefully it's a step in the right direction.)
Good luck. I've worked on an ActiveSync implementation, and recurrent events are fundamentally painful. You'll need to think about all kinds of corner cases - if something occurs every month on the 30th, what happens in February? What happens if it happens at 1.30am, and the clocks go forward or backward in the event's time zone so that 1.30am happens 0 or 2 times for a particular day?
Noda Time can help with this, but it doesn't provide a complete solution, partly because all the requirements will vary so much.
The important types you'll need to know about are LocalDate and LocalDateTime to provide time-zone-neutral dates/times, and Period which represents a not-necessarily-fixed period of time, such as "1 month". That will help with things like "add a week" - and there are methods on LocalDate for things like "next Monday after this date". It gets harder for events which are "weekly, on Monday and Wednesday" - you'll want to step through the weeks, working out which days occur within a particular week, until you've gone through all the events you need.
Noda Time 2.0 has the concept of "adjusters" which will make life somewhat simpler for things like "the first Monday of October" but everything you need to do can be done with Noda Time 1.3. (Don't wait for Noda Time 2.0, which I wouldn't expect to be released for another 6 months at least.)
I think my strongest pieces of advice would be:
Keep it simple. Focus on getting the right results first, then work out any optimizations you need. (For example, don't try to "guess" when the 100th instance of an event will occur - stepping through 100 instances with simple steps will be slower, but get you to the right answer. Do measure the performance, but make sure you have good tests before you optimize.)
Introduce your own types to represent exactly what you know about the event. Use the Noda Time types where they match of course, but don't be tempted to use an existing type just because it's quite like what you're trying to represent. The small differences will bit you eventually.
Make sure you know what you actually want the results to be. Write lots of tests. Date and time work is a naturally data-oriented domain, so invest in making it as easy as possible to write tests for all the corner cases you should be thinking of. (And you really should be thinking about them. Pay particular attention to leap years and time zones.)
Be aware that time arithmetic doesn't follow the normal rules of arithmetic - x + 1 month + 1 month isn't the same as x + 2 months
If/when behaviour surprises you, do come back to ask specific questions here. There aren't very many of us working on Noda Time, but questions tend to be answered quickly :)

When filtering search results by date, should time zone be crtieria for the date?

We have a website that has a large number of events that have dates and times created by admins. Admins choose a time zone for each date time entered, and they are stored in UTC time. We are trying to support a global audience, and be completely localized in terms of dates.
We have a search page, that allows dates to be entered as search criteria.
So users could say, show me all events between "12:01 AM July-1-2011" and "11:59 PM July 10-2011".
I'm trying to figure out what the best approach is to determining what time zone to consider the date filter criteria in.
Force end users to select a time zone when creating a date filters. This is cumbersome, and our designers our pushing back. It is what I would prefer.
Assume the the entered dates are in the users "preferred" time zone, which is set upon logging in.
Store times in Local time, without converting to UTC. This way the end users are searching in the admin created date. I hate this idea, i need help explaining why this is bad.
Please help!
Second option is possible solution to your problem. And it is probably the best.
Possibly you could get current time zone offset from web browser (with JavaScript) but the problem is, there are certain time zones that currently have the same offset but Daylight Saving Time switches on different dates, therefore search result would be inaccurate. By having User to choose his/her prefer time zone and storing that information in the profile, you could always present correct dates and times, as well as use this information for searching. However, I would add an information near search box, so that end User would know what time zone this refers to (with JavaScript that would be obvious: the current one, with profile User might forgot).
BTW. Time zone information is best to show as "UTC+02:00 (Warsaw, Zagreb, Skopje)" instead "Central European Time"...
As for other options:
1. Too much clicking. As well as "don't make me think, I want to have it in my local time zone, isn't that obvious?".
3. Local times will not be comparable against each other. You will soon end up with two different dates referring to the same point in time (at least in terms of the numbers). Really bad idea.

Resources