I feel I ask this question every 3 month. I have ...
# suitescript
d
I feel I ask this question every 3 month. I have a Unix Timestamp (server-side) that I want to display to the user in the 'User Preference' timezone. . I'm in a spiral of trial and error loop.
It needs to be a SuiteApp solution .. so, able to work on all datacenters
c
can't you pass it into new Date(...) and format it?
d
I believe that was
trial
#3 of 140.
The unix timestamp is 1677069900
c
Copy code
var myDate = new Date(1677069900 * 1000);
timestamps are in milliseconds in JS so you multiply by 1000 and then get the date
👍 1
d
Copy code
const userFormattedDate = format.format({
    value: new Date(timesheet.StartTime * 1000),
    type: format.Type.DATETIME,
});
e
I feel I ask this question every 3 month.
Time to write a utility module+function and/or add a browser snippet and/or a gitlab snippet and/or a confluence doc and/or bookmark this thread :)
plusone 3
c
^^Github Gists have been incredibly handy for me for stuff like this.
this 1
d
Agreed. How can I help?
Also, that same time needs to be used as the trandate on a timebil ... in scripts that can be run either by the user, or by the system. Ideally, the timebill trandate uses the subsidiaries timeszone in both use cases. I VA!
It seems that no matter what the user pref is, everything is save as PST
So, I think I need to discover the timezone of the employees subsidiary in this case. Arg. I don't see how I can find that out (without loading the subsidiary record itself)
I'm chasing my tail
s
I try to consider that a timestamp is actually timezone agnostic. Timezones become interesting when you go to observe a timestamp - timezone gives it context
d
Well, I chasing my tail.
I need to ensure that when I set the trandate of the timebill, it is properly aligned
s
there is that momentjs timezone library
d
I don't think it'll help
when I set the trandate of the timbill, I
think
it wants it in PST.
Assuming the startTime I get is unix/seconds ... new Date(options.startTime * 1000) .. doesn't work correctly
And, I'm in a OneWorld account where different subs have different timezones.
So, I think I have to discover the timezone first, convert the incoming startTime to a Date object in the sub's timezone, then convert THAT to PST?
b
Copy code
const userFormattedDate = format.format({
    value: new Date(timesheet.StartTime * 1000),
    type: format.Type.DATETIME,
});
looks reasonable, this should get you a string that you can use with setText
remove the time part of it and you should have a string that represents the date
theoretically you can parse the date again with format.parse if you really wanted to use setValue
r
@darrenhillconsulting If you can figure out the users/subsidiary timezone you can pass it to
format
module
message has been deleted
d
I wish it were all that easy. I should have kept track all of the different combinations I've tried.
I'm beginning to think this may not be possible to get right!
My new solution grabs the timebill's subsidiary, gets the TIMEZONE from the subsidiary record, I find the timezone offset via suiteQL against the TimeZone record. I use that info to perform the following
Copy code
convertedDate = timeZoneDetail.direction === '+' ? moment.unix(options.startTime).add(timeZoneDetail.offset, 'hours').toDate() : moment.unix(options.startTime).subtract(timeZoneDetail.offset, 'hours').toDate();
I use convertedDate as the trandate
I also tried simply converting the datetime directly to PST, and simply saving that.
It shouldn't be this hard.
Well, I can't solve this mystery.
b
what does the rest of the code look like?
it still looks like you are attempting to use setValue instead of setText, which is actually harder than just using setText
it also looks like you are using the offset to utc, which is not what you are going to be interested in
you would want the offset between pacific time, since thats what the Date would be,
d
@battk, setText is easier? Also, I'm battling several timezone issues. I have the users timezone, PST (server), and ultimately the subsidiary timezone. I'm receiving a epoch time. And I need it to save in a timebil in relation to the timebill's subsidiary timezone. I thought I've tried every combination. Are you saying I should use format.format on the new Date(epoch * 1000) and setText?
c
Ill second setText being easier. Took way too long before I realized. Would have saved me alot of headaches in the past
b
for setValue, you need to manipulate the Date
date fields ignore timezone so you need to add logic to convert between the user's timezone and the server's pacific timezone
👍 1
that means manipulating the hours of the Date and accounting for the difference in timezones
setText you only need to get the string correct, and format.format does that for date time formatting
im not really sure in what context the subsidiary timezone is different that the timezone you get from the runtime preferences, so im not sure why you think the subsidiary timezone matters
d
Well, this particular customer has 20+ subsidiaries, located all around the world. We're importing timebills from an external system that also come in globally. So a guy in Austrailia may submit hors against a Canadian subsidiary project, etc.
I'll do some testing around setText
b
ultimately only one timezone is going to be happy
if you set the date to 3/9/2023, it will be 3/9/2023 for both Australia and Canada
date fields dont change for different timezones
d
I'm ok with that, because those timebills will only be relevant for those users in a subsidiary. What's imporant is that the date itself it correct in the subsidairies timezone.
Well, just for transparency, I burned the midnight oil on this and ended up simply doing the following.
Copy code
const incomingEpochTime = 1678255200;

const startTimeDate: Date = new Date(incomingEpochTime * 1000);
const subsidiaryOffset = subsidiaryTimeZoneDetail.direction === '-' ? subsidiaryTimeZoneDetail.offset * -1 : subsidiaryTimeZoneDetail.offset; // using query module, offset is in hours
const tzDifference = subsidiaryOffset * 60 + startTimeDate.getTimezoneOffset();
const adjustedSubDate = new Date(startTimeDate.getTime() + tzDifference * 60 * 1000);

newTimeBill.setValue({fieldId: 'trandate', value: adjustedSubDate});
Not my finest work
b
looks reasonable outside of the 2 days in the year when the offset changes
you also have a prime opportunity to check that out in 2 days