1. Getting time zone and Daylight Saving Time offsets straight
There's a brilliant page collecting so many useful examples of Netcool/Impact policy functions and code fragments, called Policy Language Code Library, you can find it here.
However, I missed a simple function which would give me my local time zone and daylight saving time offset in those examples.
Many times we work with timestamps representing status changes or other metrics, expressed in GMT+0 time zone, no matter where the server was located. There are inconveniences with that approach in my view, I personally prefer UNIX Epoch timestamps. But anyhow, GMT+0 is a time you also cannot present as-is to your clients on dashboards designed for them to use every day. So let's try to get the local time out of that!
There's a bit of inconvenience I haven't solved yet: obtaining the local time zone of the server automatically from a JavaCall so if you know the way, please post it here. What I did, I assumed the IPL developers implementing this code would know the server time zone and simply pass it in function parameters. In a case developers wouldn't know how time zones are being called or which time zones are being actually supported, there's a function to get them all, actually it was also mentioned in the Policy Language Code Library too, but let me quot it here too:
function getTimeZones(tzList)
{ tzList = javacall("java.util.TimeZone", null, "getAvailableIDs", {}); } |
Executing this function and logging the output will give you all array of time zones your Impact server supports, it's 617 positions, so I won't paste an example in order to not make my post so long ;)
I'll be using time zone "Poland" in my examples further on.
So here we go: I'm using examples from Policy Language Code Library, just put this into something I need. The only input parameter is the local server time zone and two output parameters are the offsets: time zone offset vs. GMT+0 and Day Light Saving Time offset.
function f_getZoneAndDSTOffsetsInMilis(i_TZ,o_ZoneOffset,o_DSTOffset) {
if(i_TZ=="") {i_TZ="Poland";} //create a time zone object timeZone=javacall("java.util.TimeZone", null, "getTimeZone",{i_TZ}); //create a calendar object CALENDAR = javacall("java.util.Calendar", null, "getInstance", {}); //tweak calendar to reflect give time and time zone javacall(null, CALENDAR, "setTimeZone", {timeZone}); javacall(null, CALENDAR, "setTimeInMillis", {(getDate()*1000)}); //for troubleshooting... log(3,CALENDAR); ZoneOffsetInt = getFieldValue(null, CALENDAR, "ZONE_OFFSET"); DSTOffsetInt = getFieldValue(null, CALENDAR, "DST_OFFSET"); o_ZoneOffset = Int(javacall(null, CALENDAR, "get", {ZoneOffsetInt})); o_DSTOffset = Int(javacall(null, CALENDAR, "get", {DSTOffsetInt})); log(3,"Funkcja f_getZoneAndDSTOffsetsInMilis: "+o_ZoneOffset+" "+o_DSTOffset); } |
The offsets in the function above are in milliseconds. If you need the same value but in seconds, simply divide it by 1000:
function f_getZoneAndDSTOffsetsInSeconds(i_TZ,o_ZoneOffset,o_DSTOffset) {
f_getZoneAndDSTOffsetsInMilis(i_TZ,o_ZoneOffset,o_DSTOffset); o_ZoneOffset=o_ZoneOffset/1000; o_DSTOffset=o_DSTOffset/1000; } |
2. Maximum duration of months in days
I'll focus on days since it's been the most useful for my dashboards and charts so far, but based on the example below you'll easily construct your own policy to calculate your any period duration in days, hours or minutes etc.First, something trivial, but why not to simply find this post and copy-paste it to your code? ;)
Getting maximum number of days in any month. As input you need Year as integer (in format yyyy) and month as simple short integer value from range 1-12.
function f_getAnyMonthMaxDays(Year,Month,MonthMaxDays) {
if(Month==2) { if((Int(Year)%4==0) && (Int(Year)%100!=0)) { MonthMaxDays=29; } else { MonthMaxDays=28; } } elseif(Month==4 || Month==6 || Month==9 || Month==11) { MonthMaxDays=30; } else { MonthMaxDays=31; } } |
The next function will be bit different, it will return the current month maximum number of days. This is useful for a dashboard which shows the current month data and needs to spread across all days even if some of them are future.
function f_getCurrMonthMaxDays(CurrEpoch,CurrMonthMaxDays) {
CurrMonth = LocalTime(CurrEpoch, "MM"); if(CurrMonth=="02") { if((Int(LocalTime(CurrEpoch, "yyyy"))%4==0) && (Int(LocalTime(CurrEpoch, "yyyy"))%100!=0)) { CurrMonthMaxDays=29; } else { CurrMonthMaxDays=28; } } elseif(CurrMonth=="04" || CurrMonth=="06" || CurrMonth=="09" || CurrMonth=="11") { CurrMonthMaxDays=30; } else { CurrMonthMaxDays=31; } } |
Now, another bit different function giving you same information but for the month just passed. This is also useful for dashboards on which you want to compare this and last month performance of your services etc. This function needs to be smarter, as last month could be December last year which could be 1999 (or 2099). I'm not saying you'll need this function in A.D. 2100 but let's be correct and precise even in hopeless cases as a matter of having good principles ;)
function f_getLastMonthMaxDays(CurrEpoch,YearLastMonth,LastMonth,LastMonthMaxDays) {
ylm4 = int(LocalTime(CurrEpoch, "yyyy")); ylm2 = int(LocalTime(CurrEpoch, "yy")); lm = int(LocalTime(CurrEpoch, "MM"))-1; MonthsNum = {"01","02","03","04","05","06","07","08","09","10","11","12"}; MonthsDur = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 }; if(lm==2) { LastMonth = MonthsNum[lm-1]; YearLastMonth = String(ylm2); if((ylm4%4==0) && (ylm4%100!=0)) { LastMonthMaxDays=29; } else { LastMonthMaxDays=MonthsDur[lm-1]; } } elseif(lm==0) { LastMonth=MonthsNum[11]; LastMonthMaxDays=MonthsDur[11]; if(ylm2==0) { YearLastMonth="99"; } else { YearLastMonth = String(ylm2-1); } } else { LastMonth=MonthsNum[lm-1]; LastMonthMaxDays=MonthsDur[lm-1]; YearLastMonth = String(ylm2); } } |
If you want to test this function I have a bunch of examples for a month with 28, 29, 30 and 31 days:
n = GetDate();
//n = 1463305335; // Sun, 15 May 2016 09:42:15 GMT //n = 1455529335; // Mon, 15 Feb 2016 09:42:15 GMT //n = 1458034935; // Tue, 15 Mar 2016 09:42:15 GMT //n = 1426412535; // Sun, 15 Mar 2015 09:42:15 GMT //n = 953113335; // Wed, 15 Mar 2000 09:42:15 GMT f_getLastMonthMaxDays(n,ylm,lm,lmmd); log("ylm:"+ylm+", lm:"+lm+", llmd:"+lmmd); |
3. Duration of days in seconds
A very useful thing to calculate precisely duration of your day in seconds.Someone may say: hey, I know my day is 24 hours long, and every hour is 60 minutes long and every minute is 60 seconds long, which gives me 86400 seconds a day!
True, but let's also consider some countries in which time changes to winter time in October (or November) and back to summer time in March (or April).
Therefore, because of time change to something called Daylight Saving Time or back, days on Earth can be 23, 24 or 25 hours long!
What's the easiest way of calculating the real day duration in seconds?
My response is: comparing two UNIX epoch times considered as the end and the beginning of the day. By beginning of day I consider 00:00:00 time. In 24 hours clock the end of day is at 23:59:59. Let's skip milliseconds this time.
The function below returns actually two useful values: day duration in seconds and hours. You'll get 82,800 or 86,400 or 90,000 seconds long and respectively 23, 24 or 25 hours long days this way:
function f_getMaxDayDurationInSeconds(DayID, DayBeginningEpoch, DayEndEpoch, MaxDayDurationInSeconds, MaxDayFull3600sLongHours) {
MaxDayDurationInSeconds = Int(DayEndEpoch - DayBeginningEpoch + 1); MaxDayFull3600sLongHours = (MaxDayDurationInSeconds/3600); log("The day "+DayID+" was "+MaxDayDurationInSeconds+" seconds long."); log("The day "+DayID+" was "+MaxDayFull3600sLongHours+" hours long."); } |
For calculating duration of months, which may have contained 23 or 25 or just 24 hours long days only, you can use a similar function:
function f_getMaxMonthDurationInSeconds(MonthID,MonthBeginningEpoch,MonthEndEpoch,MaxMonthDurationInSeconds) {
MaxMonthDurationInSeconds = MonthEndEpoch-MonthBeginningEpoch+1; MaxMonthFull24HLongDays = Int(MaxMonthDurationInSeconds/86400); MaxMonthFull3600sLongHours = Int(((MaxMonthDurationInSeconds-MaxMonthFull24HLongDays*86400)/3600)+0.5); log("The month "+MonthID+" was "+MaxMonthDurationInSeconds+" seconds long."); log("The month "+MonthID+" was "+MaxMonthFull24HLongDays+" days and "+MaxMonthFull3600sLongHours+" hours long."); } |
This is especially useful for calculating your base for your services availability.
I hope you enjoy this post and if you have more examples or you find these examples I posted not working or incomplete, please let me know, thanks!
No comments:
Post a Comment