I have an NSArray of CFAbsoluteTimes. They should be sorted from earliest to latest, but if not I can sort them.
What I need to do is find the min and max date (e.g. Jan 1 to Jan 5) and create a bucketization that shows the count for each day between, e.g.:
Jan 1 - 1
Jan 2 - 0
Jan 3 - 4
Jan 4 - 0
Jan 5 - 3
Something like that. What is the simplest way to turn the absolute times into a rounded NSDate of some sort I can count? Intermediate forms don't really matter to me. I just need to write a function that returns a count when given a date.
You'll probably be happier working completely in Cocoa for this problem, using NSDate instead of CFAbsoluteTime.
Applicable document is the Date and Time Programming Guide.
The general approach you'll need is to work within an NSCalendar, which encapsulates all of the information about days per month, months per year, leap years, DST changes, all for a particular time zone. Convert your NSDate instances to NSDateComponent and you'll be able to extract the day and month numbers, then bucketize from there.
Remember that the function you write (return a count when given a date) will implicitly or explicitly have to handle NSCalendar and NSTimeZone values. The answer will vary by year (is it a leap year? does the interval include a leap day) and locale/date (are we observing Daylight Saving Time in this location right now?).
Related
here like these queries,
I.e: here is First date of year is calculated ,
select DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)
and here 0 are used,what is the explanation for that?
You mean "Why", obviously.
0 is an arbitrary date which is easy to write, I think 1st January 1753. It does not matter in the all-too-common dateadd(datediff()) formula, ANY date/time would be just as good if put in both the dateadd's and the datediff's arguments. But, 0 is easy to write, plus everyone is doing the same and it creates some comfort seeing it and understanding it.
The way dateadd-datediff works is this: eg in your query
DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0)
, you want the first moment of the year of getdate(). How do you do this? You ask how many years have passed, from 1st January 1753, to getdate(3 July 2018), which results in 265. You then add that number(265) of years to 1st January 1753. Because you only added the years, and not months, days, hours etc you will get 1/1/2018 00:00:00.
I want to calculate sum of activity time(HH:mm:ss) for various transactions in PDI. For example, consider 3 activity times: 1) Activity 1 - 01:22:03,
2) Activity 2 - 01:10:11 and 3) Activity 3 - 00:22:20. The sum of all this time should be 02:54:34 but the result displays negative value. How would I improve it?
I ran into your issue (and the solution) almost by accident. It's worth explaining in a bit of detail.
Date fields are not meant for durations. They define instants. If you define a date field without its date part you're actually defining it as an instant on 1 Jan 1970, which is Unix time's start.
So, if you take your first timestamp, when you set 01:22:23 as a date field you're actually setting it to be "1 Jan 1970 01:22:23". You'd expect this field to return 4923 it's value in seconds (e.g., using getTime() on Javascript). This would work out nicely for your calculations; you could then add them up, and re-format to display.
However, if you don't specify the Timezone when setting the date value, then the date field will use your LOCAL timezone settings to define that time.
So, if you're in NY timezone, defining 01:22:23 as a Date field with format HH:mm:ss returns "31 Dec 1969 6:22:23 UTC", which returns 22923 in seconds.
If you're in Paris or another city which was ahead of UTC on 1 Jan 1970, some or all of your durations may return negative values.
The reason I say I ran into it by accident is because I'm based in London, which should be on UTC in the winter. However, oddly, that was not the case in 1970 (see UNIX timestamp(0): Europe/London returns UTC+1)
So, when calculating the timestamps in London timezone, I got:
Local time, seconds in Unix time
1:22:03, 1323
1:10:11, 611
0:22:20, -2260
These numbers add up to -326.
My suggestion:
Don't define durations as dates, or timestamps; that's not what they are. Durations are time intervals. A 1h duration is worth the same regardless of the year, day or timezone you measure it in.
Instead, just parse the values in a javascript step and do the math without resorting to date parsing.
Hacks to get around the problem (which I don't recommend):
explicitly set the timezone as +0000 when converting the fields to dates;
change your computer's timezone to UTC.
How to get the difference between two dates (informix) in integer format like that
day = 15
mon = 2
year = 1
There are two sets of date/time values in Informix: DATE and DATETIME.
The DATE type is oldest (it was in the precursor to the SQL-based Informix), and represents the integer number of days since a reference date (where day 0 is 1899-12-31, so day 1 was 1900-01-01).
You get the difference between two DATE values in days by subtracting one from the other.
The DATETIME system is newer (but still old — circa 1990). You can take the difference between two DATETIME YEAR TO DAY values and get a result that is an INTERVAL DAY TO DAY (essentially the number of days).
You could also take the difference between two DATETIME YEAR TO MONTH values and get a result that is an INTERVAL YEAR TO MONTH.
However, there is no way to get a difference in years, months and days because there is no simple way to deduce that value. In fact, ISO SQL recognizes two classes of INTERVAL: those in the YEAR-MONTH group, and those in the DAY-SECOND group. You can't have an INTERVAL that crosses the MONTH/DAY barrier.
Use the MDY function :
select mdy(2,15,2014) - mdy(1,15,2014) from sysmaster:sysdual
I am trying to convert column with GMT hour to the specified time zones from the user.
I get an error when VBA attempts to subtract 18000 secs (GMT-5) from 01:00.
Selected_GMT = -18000
CellValue = "1/0/00 01:00"
New_Time = DateAdd("s", Selected_GMT,CellValue)
Is this error happening because VBA is unable to determine the hours before 00:00?
I have figured out the seconds for Selected_GMT, how can I use that to determine New_Time?
As ooo noted in a comment above, 1/0/00 is an invalid date code. However even if that was a typo in your question, the fact that the date uses a 2 digit year code begs the question "WHICH year 00?" Apologies if you already know this, but below I've extracted a recap of how Excel dates work from something that I've written elsewhere. The relevant part is "Day Zero And Before In Excel"; if the "00" actually represents *19*00 in the cell (as it will if you've just punched in "01:00 as the cell entry), you're going to run into problems subtracting from that. In which case, perhaps explicitly enter the date and time (perhaps using the current date) but hide the date component using formatting):
Excel uses a "date serial" system in which any date that you use in
calculations is represented as a positive integer value. That integer
value is calculated from an arbitrary starting date. Adding whole
numbers to a specific serial date moves you forward through the
calendar a day at a time, and subtracting whole numbers moves you
backwards... as long as you don't go past the starting date of the
serial number system and end up with a negative value. Times are
represented as fractions of a day; 0.25 for 6am, 0.5 for noon, 0.75
for 6pm and so on.
Excel Dates
In the case of Excel for Windows, the starting date is 1 January 1900. That is, if you enter the value 1 into a cell in Excel
and format it as a date, you'll see the value as 1 January 1900. 2
will be the 2nd of January 1900, 3 the 3rd of January, and so on. 367
represents 1 January 1901 because Excel treats 1900 as having been a
leap year with 366 days. In other words, every full day that passes
adds 1 to the serial date.
It's important to remember that the above relates to Excel only, and
not to Access, SQL Server or other database products (or Visual Basic,
for that matter). In Access, for example, the range of valid dates is
1 January 100 to 31 December 9999, the same range that can be stored
in a VB or VBA variable with a Date data type.
Excel And The Macintosh
Macintosh systems use a start date of 1 January 1904, neatly bypassing the 1900 leap year issue. However that
does mean that there's a 4 year discrepancy between the serial date
values in a workbook created in Excel for Windows, and one created in
Excel for the Mac. Fortunately under Tools -> Options-> Calculation
(on pre-2007 versions of Excel) you'll find a workbook option called
1904 Date System. If that's checked, Excel knows that the workbook
came from a Macintosh and will adjust its date calculations
accordingly.
Excel Times
As noted in the introduction, times are calculated as a
fraction of a day. For example 1.5 represents noon on 2 January 1900.
1.75 represents 6pm on 2 January 1900.
(Snipped a bit about the leap year bug in 1900)
From 1 March 1900 onward Excel's dates are correct, but if you format
the number 1 using the format dddd, mmmm dd, yyyy you'll get the
result Sunday, 1 January 1900. That is incorrect; 1 January 1900 was a
Monday, not a Sunday. This day of week error continues until you reach
1 March, which is the first truly correct date in the Excel calendar.
Day Zero And Before In Excel
If you use the value zero and display it
in date format you'll get the nonsense date Saturday 0 January 1900.
If you try to format a negative value as a date, you'll just get a
cell full of hash marks. Similarly if you try to obtain a date serial
number using Excel functions like DateValue, you can only do so for
dates on or after 1 January 1900. An attempt to specify an earlier
date will result in an error.
The 1904 (Macintosh) system starts from zero. (1 January 1904 has a
value of 0, not 1. Excel's on-line help describes the Mac system as
starting from January 2, but that's probably easier than explaining to
users why a serial date value of 0 works on the Mac but not Excel.)
Negative numbers won't generate an error, but the number will be
treated as absolute. That is, both 1 and -1 will be treated as 2
January 1904.
I've periods of time every 15 days, MOM and EOM.
What I need to check is if a date value on a date field is prior to the current period minus 1.
For example, if today is 12/29, the period is 12/31, and i need to check
if prior < 12/15
How can i get the EOM (End Of Month, i mean, the last day of the month) and the MOM (Middle of month, it's like every 15th of month) with GETDATE() function without doing a DATEADD with -15 days (because in feb will be fail, and i don't care the month)
Any help or work around will be preciated.
Thanks
If you need the value 15 then put it in your code.
If that is against your company's policies then challenge the person that made that policy. Writing 5 lines of code to replace two characters is not a good coding...
If writing the 5 lines made your application much more flexible then maybe I could understand, but you are still "hard coding" 15 into your comparisons.
Thinking in a work around, what I did it was this:
If actual day < 15 then get the month actual, convert to the first day of the month (01) and minus 1 day. I get the last day of the prior month. (EOM - 1 period)
If actual day > 15, then the prior period (MOM - 1 period) is: 15 of actual month.
It's a query with if structure.
If someone has a better answer, please answer it and I'll be accept it.
Thanks :)