Get DST/STD dates and times for a given timezone (Javascript) - javascript

I am developping an embedded website contained within a windows CE device.
See it as if it was the web configuration interface of your router.
Everything is contained within a really small footprint of memory, the entire website is less than 500KB with every script, html, css and icons.
We have to assume that the user that is going to 'browse' into that interface does not have access to the internet (LAN only) so no 'online' solution here.
I am looking for a solution so the user choose his timezone and the code will get all the DST/STD times and dates for the next 10-20 years at least and downloaded them to the device that will run autonomously after that and at specific dates, will change its time to DST/STD by itself. Current application is custom (not windowce api related) and needs the DST/STD date pairs.
iana.org is maintaining a db for like every location in the world. I also saw that moment-timezone (javascript interface) is 'packaging' this data in a very compact package 25kb zipped.
I need to know if it is possible to:
'Extract' a main tz list from this DB so the user can choose its own tz. I looked at their doc but example didn't work:
var itsTimeZones = moment.tz.names();
2- Extract the next 10-20 years of DST/STD dates/times for a chosen zone ? I haven't saw any documentation anywhere on this topic. But since it's kind of the purpose of such a database, i would say it must be burried in there somewhere, need a way to dig it out.
3- If moment timezone is not the right track to go, anybody has a solution that will fullfill that requirement ?
Thanxs

My solution for extracting DST list for a given zone from moment-timezone.
1. "theTz" is a numerical index from a change on a select in the webpage.
2. select is populated with "List".
var itsTz =
{
"List" : moment.tz.names(), // Get all zone 'Names'
"Transitions" : [],
};
function TimeZoneChanged(theTz)
{
var myZone = moment.tz.zone(itsTz.List[theTz]); // Get zone by its name from List
var myTime = moment.tz(moment(), myZone.name); // Start today
var myResult;
// Build transition list according to new zone selected
itsTz.Transitions = [];
do
{
myResult = GetNextTransition(myZone, myTime);
if(myResult != null)
{
itsTz.Transitions.push(moment(myResult).format("YYYY/MM/DD"));
myTime = moment.tz(myResult, myZone.name); // Get next from date found
}
}while(myResult != null);
}
function GetNextTransition(theZone, theTime)
{
var myResult;
for(var i = 0; i < theZone.untils.length; i++)
{
if(theZone.untils[i] > theTime)
{
theZone.untils[i] == Infinity ? myResult = null : myResult = new moment(theZone.untils[i]).format();
return myResult;
}
}
}
Results for 'America/Toronto:
2017/03/12,
2017/11/05,
2018/03/11,
2018/11/04,
2019/03/10,
2019/11/03,
2020/03/08,
2020/11/01,
2021/03/14,
2021/11/07,
2022/03/13,
2022/11/06,
2023/03/12,
2023/11/05,
2024/03/10,
2024/11/03,
2025/03/09,
2025/11/02,
2026/03/08,
2026/11/01,
2027/03/14,
2027/11/07,
2028/03/12,
2028/11/05,
2029/03/11,
2029/11/04,
2030/03/10,
2030/11/03,
2031/03/09,
2031/11/02,
2032/03/14,
2032/11/07,
2033/03/13,
2033/11/06,
2034/03/12,
2034/11/05,
2035/03/11,
2035/11/04,
2036/03/09,
2036/11/02,
2037/03/08,
2037/11/01,

Related

Comparing date/timestamps in JS

For a website, we're scheduling promotions through metafields: start datetime, end datetime (format "2022-12-02T13:00:00+00:00"). In JS, i'm pulling those values and comparing them to the JS current time by converting to Epoch.
Is the way i'm approaching this fool-proof?
let currentEpoch = new Date(Date.now()).getTime()
let startPromotionEpoch = new Date(response.data.shop.promotion_start.value).getTime()
let endPromotionEpoch = new Date(response.data.shop.promotion_end.value).getTime()
if(currentEpoch > startPromotionEpoch && currentEpoch < endPromotionEpoch) {
// website updates
}
As far as i'm seeing, after extensive testing, this seems to work.
One issue i'm having though, is that it's currently Wintertime. This means that i have to enter my desired datetime in the metafield minus 1 hour for it to match my code. Ideally, this is covered by the code. How would i approach this?

Node.JS V12 Trello API How to check to see if a card is overdue

I am using Node.js V12 with the the trello-node-api package installed. I am able to find all the cards in a list but when I was looking through the json API for the card Link Here I am not able to find the correct title to check to see if the card is over due. I can find if the date was completed but not when the date turns red (Which is what I want) . I am very new with Javascript and I am not sure how to check for the red due date.
Pretty much to sum it up: I dont know how to check to see if a card is over due or not.
Here is the code that I came up with so far
Const trelloNode = require("trello-node-api")("privateinfo")
trelloNode.board.searchCards(boardID).then(function(response) {
response.forEach(element => {
if (element.idList === myListId2) {
var cardLink = element.shortLink;
if () {
//if the card shows the "red due date"
}
}
})
})
```
So I basiclly awnsered my own question.
What I did is added two if statements.
The first one is checking to see if the card even has a due date. The second one is checking the current time against the due date. As I am new to javascript, this may not be the best way but this is my way.
var date1 = element.due;
var date4 = new Date("1970-01-01T00:00:00.000Z") // Reason is because cards that have no due date go back to this date so I have to exclude it.
var date2 = new Date(date1);
var date3 = new Date();
if (date2.getTime() != date4.getTime()){ // Checking to see if a card has a due date
if (date2.getTime() <= date3.getTime()){ // Checking for over due's

javascript function toString'd with dynamic values embedded?

I'm calling toString() on a function so that I can send it across the wire to a system that will apply it against an object. A simplified example is below. Here I am pushing the function as a string to a remote service, which is checking if the remote object this, which has the property timestamp, is older than cutoff which is currently always one house ago...
var functionToSend = function() {
let cutoff = new Date();
cutoff.setHours(autoApproveCutoff.getHours() - 1);
const isMatch = this.timestamp <= cutoff
return isMatch
};
foo.sendFunction(functionToSend.toString())
I'd like to be able to sent the cutoff hour (either at build or runtime), whilst maintaining functionToSend as an actual function so I can unit test and enjoy autocomplete, colourisation etc. Plus, if i end up with 100 checks for 100 different cutoff values I don't want to have to maintain them all separately.
cutoff.setHours(autoApproveCutoff.getHours() - DYNAMIC-VALUE);
Bear in mind that once the function is stringified you can't reference anything external to the function (except thos this which is the remote object).
Might be impossible. Might be more effort than it's worth. But would be interested if anyone has any ideas, short of code-gen.

Store data from an array and use it later

I had this problem which Cooper helped me to solve it (thanks again for that), but now I'm struggling with a different one. The following script will count how many times a client code will appear on another Spreadsheet using as a second condition yesterday date.
function countSheets()
{
var vA = appSh();
var td = Utilities.formatDate(subDaysFromDate(new Date(),2), Session.getScriptTimeZone(), "dd/MM/yyyy");
var mbs=getAllSheets();
//var s='';
for (var i=2;i<vA.length;i++)
{
var d = Utilities.formatDate(new Date(vA[i][12]), Session.getScriptTimeZone(), "dd/MM/yyyy");
for(var key in mbs)
{
if(vA[i][0]==key && d==td)
{
mbs[key]+=1;
}
}
}
return mbs;
}
Then I have the below code which will search in the main spreadsheet (a table) a string and when was found will return row number, also will search for the date yesterday and return the column number. Based on these information I'll get the range where I need to paste the count result from the first script.
function runScript()
{
var ss=SpreadsheetApp.openById('ID');
var mbs=countSheets();
for(var key in mbs)
{
var sh=ss.getSheetByName(key);
var rg=sh.getDataRange();
var vA=rg.getValues();
for(var i=0;i<vA.length;i++)
{
if(vA[i][1]=='Total Number of Applications')
{
var nr=i;
break;//by terminating as soon as we find a match we should get improved performance. Which is something you cant do in a map.
}
}
if(typeof(nr)!='undefined')//If we don't find a match this is undefined
{
var today=subDaysFromDate(new Date(),2).setHours(0,0,0,0);
for(var i=0;i<vA[3].length;i++)
{
if(vA[3][i])//Some cells in this range have no contents
{
if(today.valueOf()==new Date(vA[3][i]).valueOf())
{
sh.getRange(nr+1,i+1,1,1).setValue(Number(mbs[key]));
}
}
}
}
}
return sh;
}
PROBLEM: I have 24 rows on the main Spreadsheet. So I will need to write the same script 24 times. As example, I need to count Total Number of Applications, Total Number of Calls, Number of Live Adverts and so on. If I do this it will exceed execution time since each script takes on average 25 seconds to run.
I did some researches on this website and internet and read about storing values and re-use them over and over. At the moment my script will have to go every time through the same file and count for each condition.
Q1: Is there any chance to create another array that contain all those strings from the second script?
Q2: How to use PropertiesService or anything else to store data and don't have to run over and over getValues() ? I've read Google Documentation but couldn't understand that much from it.
I hope it all make sense and can fix this problem.
My best regards,
Thank you!
My Approach to your Problem
You probably should write it for a couple of rows and then look at the two of them and see what is unique to each one. What is unique about each one is what you have to figure out how to store or access via an external function call.
The issue of time may require that you run these functions separately. I have a dialog which I use to load databases which does exactly that. It loads 800 lines and waits for 10 seconds then loads another 800 lines and wait for ten seconds and keeps doing that until there are no more lines. True it takes about 10 minutes to do this but I can be doing something else while it's working so I don't really care how long it takes. I do care about minimizing my impact to the Google Server though and so I don't run something like this just for fun.
By the way the 10 second delay is external to the gs function.

Titanium HealthKit Module - Cant create StatisticsQuery with Cumulative & Separate by source

Im trying to create a Ti.Healthkit.StatisticsCollection where I can fetch number of steps taken, grouped per day. The thing is that I also need all sources, so I can filter ("manually") all steps added through Apple Health (manually) and other sources than the device and apple watch.
So; I've set up the Statistics query, everything looks fine. I can fetch all sources for each date. BUT, here's the thing, I can't no matter what, get the number of steps taken, per source.
var query = HealthKit.createStatisticsCollectionQuery(
{
type : HealthKit.OBJECT_TYPE_STEP_COUNT,
filter : HealthKit.createFilterForSamples(
{
startDate : date_from,
endDate : date_to
}),
options : HealthKit.STATISTICS_OPTION_CUMULATIVE_SUM | HealthKit.STATISTICS_OPTION_SEPARATE_BY_SOURCE,
anchorDate : anchorDate,
interval : 3600*24, // 24 hours
onInitialResults : function(e)
{
if (e.errorCode !== undefined)
{
//Utils.showError(e);
}
else
{
for(var i in e.statisticsCollection.statistics)
{
var statistics = e.statisticsCollection.statistics[i];
console.log(statistics.sources[0]);
var quantity = statistics.getSumQuantityForSource(statistics.sources[0]);
var stepCount = quantity.valueForUnit(HealthKit.createUnit('count'));
console.log(statistics.sources);
//console.log(statistics.startDate);
console.log(stepCount);
for(var k in statistics.sources)
{
var _source = statistics.sources[k];
var quantity = statistics.getSumQuantity(_source);
console.log(_source);
console.log(quantity);
I have tried to follow the Apple docs as well as the Ti.HealthKit docs, and as far as I can see I've tried everything now. I've also tried to fetch the steps while I iterate all sources, to put it inside the statistics method;
sumQuantityForSource(_source)
but that only returns "null".
I can get the number of steps for a day, but it contains all sources steps..
Does anyone have any suggestion what to try? I feel like I've tried everything possible.
well okey, I worked with this for 5 hours and 10 min after this post I found out what I did wrong. I should have checked if "quantity" was null (var quantity = statistics.getSumQuantity(_source);) and just continue to the next iteration, because down the results array, i hit sources with steps..

Categories