Convert sting in datetime like excel format cell does in t-sql - excel

I have END_Date data like 43830.99931. When I paste it in the excel and format the cell to Date. It convert it to 12/31/2019 11:59:00 PM. I want same functionality in T-SQL. How can I achieve same result using T-SQL?

Excel (by default) uses the 1900 date system. This simply means that the date 1 Jan 1900 has a true numeric value of 1, 2 Jan 1900 has a value of 2 etc. These values are called "serial values" in Excel and it is these serial values that allows us to use dates in calculations.
The code to convert:
DECLARE #SerialDate FLOAT;
SET #SerialDate = 43830.99931;
SELECT CAST(#SerialDate - 2 AS DATETIME);
returning back the date time value of:
2019-12-31 23:59:00.383
You may have noticed the -2 in the cast. That's because Excel, due to issues with 29th Feb 1900 and the inclusiveness of the start/end dates. (1900-01-01 is day 1 not day 0, and 1900 was not a leap year but excel calculates it wrongly) we have to subtract 2. Details on that issue can be found here.

Related

How do I get a string value of the 5 digit serial date format from a cell into my script?

I have a formula in a cell that is doing a vlookup to another sheet by combining the values of two cells on my spreadsheet. It's a table of names on the left and dates up top. I'm combining the name and date values into a single string value and using that as by vlookup key value, which works great. Now I need to basically do the same thing in my google script, but the date value has me at a loss. In the vlookup cell formula, the date value is the 5 digit date serial code. However when I combine the two cell values in my script, I cannot get the same 5 digit serial code out of the cell. I have tried all conversions of number, string, text, ect. What function can I use to get this 5 digit date value as a string in my script?
function serialDatevalue(){
var WB = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var NewDate = new Date();
var NewDate = WB.getRange('B1').getValue();
var JSdate = WB.getRange('B1').getValue();
Browser.msgBox(Number(NewDate));
// Some others that I have tried
// var JSdate = Date.parse(DateValue);
// var JSdate = Number(DateValue);
// var JSdate = Utilities.formatDate(DateValue, 'PST', '%');
}
for example, April 13, 2019 = 43568. I want to get this 5 digit value as a string.
I keep getting 'Sat Apr 13 2019 00:00:00 GMT-0700 (PDT)', or other longer integer values.
Please help.
From Tanaike's answer to Getting the number equalent of duration using GAS
var serialNumber = (dateObject.getTime() / 1000 / 86400) + 25569; // Reference: https://stackoverflow.com/a/6154953
The easier way to get the serialized number corresponding to a certain cell date value in Google Sheets is by using a the built-in Google Sheets function [TO_PURE_NUMBER][1]. This because Google Sheets and JavaScript, which is used by Google Apps Script, used different epoch (reference date used as 0 for the serialized numbers) and use different time units.
From https://developers.google.com/sheets/api/guides/concepts#datetime_serial_numbers
Date/Time serial numbers
Google Sheets, like most other spreadsheet
applications, treats date/time values as decimal values. This lets you
perform arithmetic on them in formulas, so you can increment days or
weeks, add or subtract two date/times, and perform other similar
operations.
Google Sheets uses a form of epoch date that is commonly used in
spreadsheets. The whole number portion of the value (left of the
decimal) counts the days since December 30th 1899. The fractional
portion (right of the decimal) counts the time as a fraction of one
day. For example, January 1st 1900 at noon would be 2.5, 2 because
it's two days after December 30th, 1899, and .5 because noon is half a
day. February 1st 1900 at 3pm would be 33.625.
Note that Google Sheets correctly treats the year 1900 as a common
year, not a leap year.
By the other hand, JavaScript use January 1, 1970 00:00 UTC as the epoch date and use milliseconds as the unit.
A word of caution: Custom code to make serialized number conversions from one to the other should consider if the spreadsheet and the Google Apps Script are using the same timezone or not.
Related
How to read value of fetched cell data as date google sheets API
Getting the number equalent of duration using GAS

Power Query - Create date from datenumber and time column

In Excel's powerquery editor I have two columns. One is a daynumber (1 to 365) and the other is the time. I would like to merge the two columns to a datetime column. Day 1 will correspond with 01-01-2000. How can I do this?
For example:
column 1: 365,
column 2: 02:00:00
Transform column 3: 31-12-2000 02:00:00.
You can use this to add a column which combines the relative date and time values:
= Table.AddColumn(#"Changed Type", "DateTime", each DateTime.FromText(Date.ToText(Date.AddDays(#date(1999,12,31),[#".1"])) & " " & Time.ToText([#".2"], "hh:mm:ss")), type datetime)
Check your logic for the date of Day 0, though - if day 1 is 01/01/2000 then day 365 <> 31/12/2000...
Excel dates are built up on float values where the integer is the number of days passed since 1900-01-01 and the fraction is the time of day.
With that in mind 2000-01-01 is 36526.
With the formula:
=36526+A1+B1
You get the datetime value, then just set the prefered cell format
With this formula 365 + 02:00:00 will become as you expect in question.
But 1 can't be 2000-01-01 then, it has to be 2000-01-02. Or you need to specify where to remove a day becasuse the math does not add up.

How does Excel convert 12 hour time (text values) into decimal numbers?

I'm trying to find the manual function on how Excel converts am/pm time (text) values into numeric decimals (using the Format menu > Number while selecting my 12 hour time column).
For example, how does 12:30:00 PM turn into 0.52083?
Thank you.
Date and time can be handled in many ways. The time representation you are observing in Excel is based on 1 day = 24 hours = 1.0. So 12:00 pm should be exactly 0.5, while 12:30:00 pm would be a bit (30/(24*60) = 1/48 = 0.0208333) above.
Btw. 12/24 hour is just a region specific presentation issue. Internally this doesn't affect the actual date and time values.

Including start year and end year in YEAR calculations

For the calculation I'm trying to perform one year = one season and the data I have is start year and end year.
So 1952 1953 needs to add up to 2 (seasons) but if I use =YEAR(A1)-YEAR(A2) the result is 0 - is there a simple way to include the start year and end year as a value in these calculations?
It looks like you have found the problem and rectified it. For the benefit of others who might have found this thread, this is why it was behaving the ways it was.
Background - Excel (and many other applications) treat dates as 1 for every day past Dec 31, 1899. Today happens to be 42,079. Time is a decimal portion of a day so 42,079.75 would be Mar 16, 2015 06:00 PM.
You had the years as numbers in A1:A2; not as full dates. Using the 1-per-day formula, 1952 is May 5, 1905 and 1953 is May 6, 1905. If you peel out the year of each of those with the YEAR() function, you are subtracting 1905 from 1905; resulting in zero.
The solution would be to either type full dates into A1:A2 and format the cells as yyyy so they display 1952 & 1953 but retain their full date nature e.g. =ABS(YEAR(A1) - YEAR(A2)) + 1 , or use the years as numbers only and discard the YEAR() function altogether, e.g. =ABS(A1 - A2) + 1 to get the spanned (inclusive) number of seasons.

Find the Earliest Date in Excel

i want to find the earliest date between the DOB OF FATHER & DOB OF MOTHER in sheet1, by matching the employee code and having the value in earliest date in sheet 2.
Sheet 1
Employee Code DOB OF FATHER DOB OF MOTHER
28883 29/12/1987 28/01/1988
83933 19/11/1988 12/07/1988
55428 21/01/1938 03/10/1938
99999 18/03/1982 11/02/1980
Sheet 2
Employee Code Earliest Date
28883
99999
83933
55428
Sheet1:
A B C
1 Code FatherDOB MotherDOB
2 28883 29/12/1987 28/01/1988
3 83933 19/11/1988 12/07/1988
4 55428 21/01/1938 03/10/1938
5 99999 18/03/1982 11/02/1980
Sheet2:
A B
1 Code EarliestDOB
2 28883 29/12/1987
3 99999 11/02/1980
4 83933 12/07/1988
5 55428 21/01/1938
You can combine two vlookup operations with a min operation:
=MIN(VLOOKUP(A2,Sheet1!$A$2:$C$5,2,FALSE),VLOOKUP(A2,Sheet1!$A$2:$C$5,3,FALSE))
The first vlookup gives you the father's date of birth (using the entire table range but extracting the second column) and the second gives you the mother's date of birth (extracting the third column).
The earliest is then simply the minimum of the two.
If some of the dates may be blank, the easiest solution is probably to set up a D column on sheet 1 to evaluate the earliest date, ignoring blanks. For example D2 would have (split across lines for readability):
=IF(ISBLANK(B2),
B3,
IF(ISBLANK(C2),
B2,
MIN(VLOOKUP(A2,$A$2:$C$5,2,FALSE),
VLOOKUP(A2,$A$2:$C$5,3,FALSE))))
If one of the cells is blank, it uses the other, otherwise it chooses the earliest.
Then you just lookup that new column D in the formula on sheet 2 (example for B2):
=VLOOKUP(A2,Sheet1!$A$2:$D$5,4,FALSE)
I wanted to point out a limitation that has been in Excel forever.
Excel internally doesn't handle dates before 3/1/1900 (March 1, 1900) correctly.
it thinks that 1900 was a leap year
that the day before 3/1/1900 is 2/29/1900
if you enter pass Excel through automation any date between 12/31/1899 and 2/28/1899, it will think it is 1/1/1900 - 2/29/1900
if you attempt to pass it through automation 12/30/1899, it will think it is January 0, 1899.
if you attempt to pass it any date before 12/30/1899, it will throw an error
Various example dates that you can pass to Excel through automation:
Date Excel
-------- ------------------------------
18651001 throws error going into Excel
18991201 throws error going into Excel
18991229 throws error going into Excel
18991230 shows as "12:00:00" in Excel; it refuses to show a date portion
18991231 shows in Excel as 1/1/1900
19000101 shows in Excel as 1/2/1900
19000102 shows in Excel as 1/3/1900
19000103 shows in Excel as 1/4/1900
19000201 shows in Excel as 2/2/1900
19000228 shows in Excel as 2/29/1900
19000229 Feb 29 1900 was not a real date; Excel takes it
19000301 shows in Excel as 3/1/1900
19000601 shows in Excel as 6/1/1900
19001231 shows in Excel as 12/31/1900
19010101 shows in Excel as 1/1/1901
20151128 shows in Excel as 11/28/2015
The VARIANT structure does dictate that a date must be after December 30, 1899 midnight as time zero:
2.2.25 DATE
DATE is a type that specifies date and time information. It is represented as an 8-byte floating-point number.
This type is declared as follows:
typedef double DATE;
The date information is represented by whole-number increments, starting with December 30, 1899 midnight as time zero. The time information is represented by the fraction of a day since the preceding midnight. For example, 6:00 A.M. on January 4, 1900 would be represented by the value 5.25 (5 and 1/4 of a day past December 30, 1899).
tl;dr: If you have any dates in Excel before March 1 1900 (e.g. the birthdate of the oldest woman alive), Excel will not perform the math correctly.
If you wish to display any date before 3/1/1900, it should be presented as text, rather than an actual date.
Anyone attempting to find the minimum date in a range needs to be aware of this limitation in Excel.

Resources