How to get date class and POSIXCt give the same result - excel

I am reading in some numbers from excel that are the numeric version of a date. Excel displays 42094 as 3/31/15 (or some variant depending how the Date is structured.
as.Date(42094,origin = "1899-12-30") produces "2015-03-31". The choice of origin has to do with Microsoft misunderstanding about leap years.
These two lines of code
temp <- as.Date(42094,origin = "1899-12-30")
as.POSIXct(temp, origin = "1899-12-30")
produce
"1899-12-30 04:41:34 MST"
With
as.POSIXct(temp, origin = "1900-1-1")
the result is
"2015-03-30 18:00:00 MDT"
Now what I want is
"2015-03-31 MDT"
or something similar

Part of the solution to my problem was this line of code.
origin=as.POSIXct("1970-01-01", tz="America/Denver")
With the usual way of using origin (origin = "1970-01-01"), GMT is assumed; this code changes that to a local time zone.
The code from #pnuts converts days to 2015-3-31 from the microsoft 1900 origin (42094) to the R origin of 1970-1-1 (25569). It then converts days to seconds (86400) and then adds my hours B1 converted to seconds. So here's a couple of lines of code that do what I want for the date part of my data.
temp <- (42094-25569)*86400
as.POSIXct(temp, origin=as.POSIXct("1970-01-01", tz="America/Denver"))
The result is
"2015-03-31 01:00:00 MDT"

Related

How to query date by year?

Following query in SQLite Studio for a date in 2021 or 2022 returns all rows correspondingly:
select * FROM daily_reports
WHERE strftime('%Y', daily_reports.reporting_date) in ('2021','2022');
Same query in Python returns no rows and the where clause
created is ... where 1 = 0:
q = ...
q = q.filter((func.strftime('%Y', DailyReportItem.reporting_date) in ['2021','2022']))
How to make it work?
The problem is that the statement you passed into .filter() does not get converted into SQL, it is executed as false in Python right away and then passed down to .filter() as argument.
The way you do the IN operator in SQLAlchemy is via DailyReportItem.reporting_date.in_(['2021', '2022']).
So in your case it should be something like this: q.filter(func.strftime('%Y', DailyReportItem.reporting_date).in_(['2021', '2022']))
I would rather just check if date is bigger than the beginning of the year 2021 and lower than the end of 2022. This way you would also get a better use of indexes.

Nodejs change time at date type after getting from Mongodb

I wanted to change time at date type which returning from mongodb with custom time like below
"2021-05-26T00:00:00.000Z"
to
"2021-05-26T10:20:00.000Z"
I wanted to change time from a variable at the date, so my technique was split this date with "T" then get time part and change it with custom time
let splitedTime = timev[0].validFrom.toString().split()[0];
let customTime = "10:20:00.000Z";
let finalTime = splitedTime + customTime;
but this split not working this giving me date like this "Wed May 26 2021 06:00:00 GM". Can you please help me for this?
Working with Date
Whilst I understand your logic of converting it to a string and then using string methods to convert it to your desired output, I believe a simpler approach is to use the Date object
function dateAdd(original, hours, minutes) {
const date = new Date(original);
date.setHours(original.getHours() + hours);
date.setMinutes(original.getMinutes() + minutes);
return date.toISOString();
}
When original = "2021-05-26T00:00:00.000Z" then the return value is "2021-05-26T10:20:00.000Z".
If you want a fixed time:
const date = new Date('2021-05-26T00:00:00.000Z');
date.setUTCHours(10);
date.setUTCMinutes(20);
date.setUTCSeconds(0);
date.setUTCMilliseconds(0);
// a cleaner approach:
date.setUTCHours(10, 20, 0); // hoursValue, minutesValue, secondsValue
console.log(date.toISOString());
Which produces the following:
"2021-05-26T10:20:00.000Z"
Another Solution
Your actual problem is being caused by the fact you call toString which returns a date string in the format of "Tue Aug 19 1975 23:15:30 GMT+0200 (CEST)" so when you're splitting by "T", that's way down at the end. toISOString will return the correct format.
Explanation
As you can see above, we avoid using string methods and use the methods that exist on Date. This approach is safer as you avoid issues with the difference between toISOString and toString. You may also find moment useful if you're using dynamic methods of changing dates regularly.
Note
In all honesty, I'm not entirely sure I understand the why behind what you're doing, so if I'm wrong please correct me so I can update my answer to be more relevant for you.
Learn More
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Why does new Date(year,month,day) not return an equivialent Date?

one day I fiddled with vanilla NodeJS using the node command line tool. (I am using node v13.11.0)
I tried to create a new Date at the 01.01.1970. I used the usual new Date(year, month, day) constructor.
As simple as it sounds, I entered new Date(1970, 1, 1) and found out, that it does not return 1970-01-01T00:00:00.0000Z. Instead, it returns 1970-01-31T12:00:00.000Z.
Has anyone an Idea, why this constructor does not return the equivalent date?
The constructor does more or less what you think:
x = new Date(1970,1,1)
1970-01-31T14:00:00.000Z
> x.getMonth()
1
> x.getDate()
1
> x.getHours()
0
(Note that months count from zero, so you requested the 1st of February).
But if you display the whole date as a string, it's showing the time in UTC, which might not be what you expect.

Moment.js sets dates to 1 day behind

I am using 2.22.1 to format dates.
When i put in a date that comes from a date selector, moment will put the date back one day. For example, when I try to format a date in the following way:
Example 1:
const day = new Date(value).getDate();
const month = new Date(value).getMonth();
const fullYear = new Date(value).getFullYear();
console.log('day', day); // 7
console.log('month', month); // 5
console.log('fullYear', fullYear); //2018
Formatting function:
moment.utc(new Date(month + ' ' + day + ' ' + fullYear), 'MM-DD-YYYY').format('DD-MM-YY')
Output: 06-05-18
Expected: 07-05-18
Example 2:
Input: Thu May 31 2018 00:00:00 GMT+0100 (GMT Summer Time)
Formatting function:
moment.utc(new Date(value)).format('DD-MM-YY')
Output: 30-05-18
Expected: 31-05-18
moment.utc will convert the input to universal time.
You are running new Date(...) with an input that's based on GMT +1.
If you think about this, it makes total sense.
Your output is 30-05-18, because it's 11 PM / 23:00 o'clock on the previous day.
This (how ever) would in fact work:
moment('05-06-2018', 'MM-DD-YYYY').format('DD-MM-YY')
// alternatively (and preferrably) this:
moment.utc('05-06-2018', 'MM-DD-YYYY').format('DD-MM-YY')
and output: "06-05-18"
Because the non utc version does not take a time input in this example.
One of the reasons moment.js exists, is to get rid of Date in your code all together.
(Keep in mind tho, that Date has drastically improved now. DateTimeFormat is a game changer)
Please just read the momentjs documentation on how to properly use moment.
edit:
If you want to process 400000 dates with this, I'd advise using RegExp, .split, .exec, .slice or Date instead.
(I can relate since I wrote a client sided Log parser with javascript generators and Service Workers for a statistical anti-cheat analysis)
I truly recommend playing around with such things to raise your knowledge.
I just ran into this issue and a quick fix I found for the time being processed in "Zulu time" (due to the Z at the end of the string) is to add .LocaleString() after the date variable.
I find that for data consistency, it's easier to store data in UTC time and then convert it to the locale string when displaying the data to the user.
For example, I'm using:
moment.utc(dateVariable.toLocaleString()).format("MM/DD/YYYY")

passing Jan of selected year by default in prompt

I have 2 year-month prompts. If I don't select any year-month in 1st prompt, report should by default, run from January of the same year, selected in 2nd prompt. My prompts are value prompts and have string values. Please help me materialise the requirement. I have already tried # prompt macro, ?prompt?, case when etc. I am nto sure, If javascript would help.
I'm going to assume your underlying date fields are not stored as DATE value types since you're using strings. This may be easier split into 4 prompts: from month, from year, to month, to year.
The filter would then be an implied if:
(
(?FROM_YEAR? = '' or ?FROM_MONTH? = '') and
[database_from_month] = '01' and
[database_from_year] = ?TO_YEAR? and
[database_to_month] = ?TO_MONTH? and
[database_to_year] = ?TO_YEAR?
)
OR
(
(?FROM_YEAR? <> '' or ?FROM_MONTH? <> '') and
[database_from_month] = ?FROM_MONTH? and
[database_from_year] = ?FROM_YEAR? and
[database_to_month] = ?TO_MONTH? and
[database_to_year] = ?TO_YEAR?
)
The above style filter is superior for many reasons:
More likely to be sargeable
Easy to understand
Uses simple built-in Cognos functions; more likely to be cross-version compliant
No issues with cross-browser support you would get with Javascript
Code snippet would work in other Cognos studios (Business Insight, etc)
You've likely seen CASE statements in filters throws an error. The CASE statement is passed to SQL, not compiled into a SQL statement via Cognos. Hence it's not seen as proper syntax.

Resources