I've spent an hour looking for answers and trying different things so I appreciate any help here.
The following code works great for finding someone's part B effective date. However, when someone's birthday is really on the 1st of a month the 'if' function get's used, and I'm no longer able to format and write the date. It's almost like 'partB_eff' is no longer a date object. (I'm a newbie, so I might just be making this part up.)
I'm getting the error "TypeError: partB_eff.toLocaleDateString is not a function at AutoFill_6_Step_Checklist(Code:24:27)"
How can I resolve this?
let birthday = new Date(e.values[2]);
//this is a date entered from a google form
let bdayCopy = new Date(birthday);
//I created this since I'll be using .setMonth(), and I don't want to change the original date of the birhtday
let bday65 = new Date(bdayCopy.setMonth(bdayCopy.getMonth()+780));
//finds the 65th birthday
let partB_eff = new Date(bdayCopy.setDate(01));
//find's the Medicare part B effective date (the 1st of the month someone turns 65)
if(birthday.getDate()==1){
partB_eff = partB_eff.getMonth-1;
//if the person's birthday is really on the 1st of the month, the part b effective date is the 1st of the month prior. partB_eff must be converted
}
partB_eff = partB_eff.toLocaleDateString('en-us',{year:"numeric",month: "short",day:"numeric"});
//format partB_eff so that it looks nice on paper
partB_eff = partB_eff.getMonth-1;
Doesn't do what you think it does. What it does is get the vound function getDate from your date object, and attempt to subtract one from it. In any other language trying to do subtraction on a function would be a type error, but Javascript is Javascript and allows numeric operations on almost any type. A function minus a number in JS is NaN. NaN doesn't have a method called toLocaleString, hence the error.
What's interesting is that you did the same operation correctly above with bdayCopy.setMonth(bdayCopy.getMonth()+780)
Just do the same thing here
bdayCopy = new Date(bdayCopy.setMonth(bdayCopy.getMonth()-1));
Also some important concepts. if in Javascript is not a function. if is a keyword that starts a conditional statement. You can't do any of the things you can do with a function with if. You can't call it or assign it to a variable or pass ot as a function argument. Clearly understanding what a function is is something you need to do to be able to work in JS, or frankly any other language.
Finally if you are doing date math in JS I strongly recommend you use a date library like DateFns or Moment. Javascript native date APIs are possibly the worst designed date API of any language ever.
I've got a javascript app that the user insists that regardless of location of the app user, they want date/times entered by the user in Eastern time. That they will be sent to the database and stored, and later displayed again in the app and displayed in Eastern timezone.
So I was looking to use moment.js and moment-timezone, but can't figure out how to make it work.
When I try const objMoment = moment(), objMoment appears to contain a time offset from the current time.
I was wanting to get a moment object that is whatever time, and then objMoment.tz("America/New_York")
but I ended up with a time that is 5 hours off from what it should be.
const objMoment = moment();
const objEastern = objMoment.clone().tz("America/New_York");
debugger;
formData.SwoDate = objMoment.toDate();
debugger;
A few things:
You don't need to create a local moment and clone it. You can instead construct a moment directly in a specific time zone with:
moment.tz('America/New_York')
Since you call toDate(), the result is always going to be a Date object that represents "now". It doesn't matter if that comes from a Moment that's been set to a different time zone or not. It's the same moment in time.
moment().valueOf() // 1600198416842
moment.utc().valueOf() // 1600198416842
moment.tz('America/New_York').valueOf() // 1600198416842
new Date().valueOf() // 1600198416842
Date.now() // 1600198416842
If you want to see the time in a different time zone, you would need to use a function like format instead.
moment.utc().format() // "2020-09-15T19:33:36Z"
moment.tz('America/New_York').format() // "2020-09-15T15:33:36-04:00"
Moment is a legacy library. You should probably choose a different library, or perhaps no library at all. Please read: Moment Project Status
I have an announce website, at the moment, I have a Subscribe form who ask the user to give me his timezone
$builder->add('timezone', ChoiceType::class, array(
'choices' => $choices
));
but I would like to change and take this information directly without asking the user in a form.
It's important for me because I will have a lot of users who will certainly not know their timezone and will choose a bad one.
Actually, I have announced who is the store with a date in GMT timezone but I would like to display them in the timezone from someone who is registered or not on my website.
For display i have two function:
{{ clanwar.rendezvous|localizeddate('full', 'short') }}
{{ clanwar.rendezvous|date("d F Y, G:i e P", user.timezone)}}
The first one gives a date with the default timezone and it takes the timezone from the server. (i can change by defining it manually)
The second one needs to have a timezone from a registered user.
So both option can't be used for what I want to do.
I think I need to use a Javascript function. I would like to store the user timezone in my session and calculated all date with this information.
But I didn't find a good function who can just find this element.
Do you know something who can help me?
Thanks
{{ clanwar.rendezvous|date("d F Y, G:i e P", user.timezone)}}
In this way you clearly would need to store the timezone in a User entity or something like that. But this is prone to change, as user can tend to travel/move they might not be so disciplined when it comes to changing the timezone each time.
What I would suggest to is to display ISO formatted date in UTC in a, for example, <div> element with a special class:
<div class="user_timezone_container">{{ clanwar.rendezvous|localizeddate('full', 'short') }}</div>
And then do a little bit of JS scripting:
$('.user_timezone_container').each(function(){
var m = moment($(this).text()); //example: "2018-04-03T09:30:26Z"
$(this).text(m.local().format('YYYY-MM-DD HH:mm:ss'));
})
I pieced the example above from the SO question Moment Js UTC to Local Time
Obviously, you don't need neither jQuery not MomentJS, but I used them here for convenience...
I'm working on a single page chat application, and when displaying the message sent by some user ,I want all the other users to see the same exact time the message was sent in and also the correct time regardless user's computer time or any other reason. As I understood UNIX time do the job ,and I want to use it in my app and put it inside datetime HTML attribute . Is there a way to do that in HTML or should I use JS for that?
Note: I think that this question isn't relevant to me because first I want to use the attribute datetime and second thing I want to use Unix time .
Any help is appreciated.Thank you.
Something like this?? You can set the dateTime attribute of the time tag with the date.toISOString function since it is one of the supported formats by the time tag.
var unixTime = 0; // fill in your epoc time here.
var isoTime = new Date(unixTime).toISOString()
timeEl.textContent = unixTime+' --- '+isoTime+' --- '+new Date(isoTime).toString();
timeEl.setAttribute('datetime', isoTime )
<time id="timeEl"></time>
I'm writing a webapp in JSF 2.0 that displays Timestamps as part of the information to the user.
I would like the user to see the timestamps localized to their location (browser's locale).
So far, whatever I did, the timestamps would always appear localized to the timezone of the server.
I tried getting the locale with these methods:
Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
or
Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
Both returned the server's locale.
I then use the locale object with SimpleDateFormat to print timestamps.
Am I using the correct API?
I've read somewhere that you have to use client side code (Javascript) to get the browser's timezone. Is that correct? How would you do that?
Thank's 'n' Advance.
UPDATE found this (jsTimezoneDetect) JavaScript code. But I'm still not sure how to translate the timezone to a Java Locale Object
You probably should use built-in formatting tag instead of SimpleDateFormat. Your question implies that you want to show date and time to International user, and in this case you should really use user's local format (they tend to differ, you know).
In case of time zone, it has nothing to do with Internationalization and Localization, i.e. there are several different time zones in USA. There are two approaches you can use here:
Store time zone information in the user profile (if you have one). This is the easiest way and allow you to use built-in <f:convertDateTime> tag.
Get time zone information from web browser. You can get it via Ajax request just like in Ben's example. Technically you can also use <f:convertDateTime> tag here.
You can send the timestamps in UTC in some common, locale-independent (or invariant if you prefer) format, parse it on the client side to create JavaScript's date object and format for locale with Globalize.
Some examples will follow but let me explain something first.
Locale browserLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
This will give you web browser's locale (but not time zone, since this is not locale related). It will actually read the contents of HTTP Accept-Language header and choose the best possible locale. If it is not working for you, please make sure that you have correctly set supported locales in your faces-config.xml. By best possible Locale, I understand that it will try to use user's most preferred Locale (if that's supported by your application), then second best and so on. If none of the Locales is supported, it will fall-back to your application's default Locales (again, faces-config.xml has to have this setting) or to server's default Locale if this setting is missing (or at least I think so, it kind of makes sense).
Locale browserLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
This one will give you the top Locale from Accept-Language header. Please check your web browser's settings - there is almost no way for it to give you the server Locale, unless they are exactly the same as your web browser's. It can give you server's defaults if and only if, none of the web browser's Locale is supported by JVM (which seems a bit unlikely).
BTW. FacesContext.getCurrentInstance().getExternalContext().getRequestLocales() will give you the Iterator so you can manually iterate through the list of Locales in Accept-Language header. It is just to let you know, you probably should not use it (UIViewRoot is really enough).
Now, suppose you have some bean with the user profile and the method which will give you the time zone. This method is better than Ajax call, in the sense that it might happen that two different time zones have the same UTC offset but switch Daylight Saving Time on different date (in other words some timestamps would be printed incorrectly). Anyway, in case like this, you can format your time-stamp like this (date also come from some bean):
<h:outputText value="#{someBean.timestamp}">
<f:convertDateTime type="both" dateStyle="default" timeStyle="default" timeZone="#{userProfile.timeZone}" />
</h:outputtext>
Now let me explain the attributes:
type - what to show, both means date and time
dateStyle - style of date (out of short, medium, long, full, default). You should really use default here as this will use the most proper format for each Locale
timeStyle - similar to date style but for time part
timeZone - takes either an UTC offset (so you don't need to convert anything) or time zone name (i.e. America/Los_Angeles).
The tag will use current view Locale by default, so you do not have to worry about this part, especially if you set up Locale support correctly.
Combining it with Ajax (see Ben's answer) would be easy enough (I think).
I also mentioned that you can write out invariant dates, parse them on the client-side and then format them with Globalize. Assuming that you have parsed date already (it depends on the representation you want to use, so I will skip this part), it could be done like that:
// you also have to assign the culture based on UIViewRoot locale and send it out with JavaScript
Globalize.culture(theLocale);
var formattedDateTime = Globalize.format(parsedDateTime, "f"); // this will use short date time format
Unlike Java, Globalize have only short ("f") and long ("F") date and time formats. So I decided on using short one.
Please also keep in mind, that Globalize cultures are separated via hyphen, not underscore, so you need "fr-CA", not "fr_CA" for example.
Please let me know if you want to use that method and need more concrete example.
Succeeded.
Here is what I did:
Added to JSF a hidden input field so I can send JavaScript values to the server:
<h:form prependId="false">
<h:inputText id="timezone_holder" value="#{bean.timezone}" styleClass="hide">
<f:ajax listener="#{bean.timezoneChangedListener}"></f:ajax>
</h:inputText>
</h:form>
Using the plugin above, I ran JavaScript code that retrieved the offset of the browser.
$(document).ready(function() {
var timezone = jstz.determine_timezone();
$("#timezone_holder").val(timezone.offset());
$("#timezone_holder").change();
});
When the timezone input is changed (initiated from the javascript code above) I run this code in the eventListener:
String strFromJavaScript = getTimezone();
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext()
.getRequest();
Locale browserLocale = request.getLocale();
TimeZone tz = TimeZone.getTimeZone("GMT" + strFromJavaScript);
// set time zone
SimpleDateFormat formatter = new SimpleDateFormat("MMM d, yyyy, HH:mm", browserLocale);
formatter.setTimeZone(tz);
Then, whenever I need to format a date I use the Date Formatter that was created above.
Another option would be to create a cookie on a Javascript that executes when the home page is ready. After that, the cookie will exist on each subsequent request and would be available
Your Javascript could use jQuery and jsTimezoneDetect
$(document).ready(function() {
setTimezoneCookie();
});
function setTimezoneCookie() {
var timezone = jstz.determine().name();
if (null == getCookie("timezoneCookie")) {
document.cookie = "timezoneCookie=" + timezone;
}
}
function getCookie(cookieName) {
var cookieValue = document.cookie;
var cookieStart = cookieValue.indexOf(" " + cookieName + "=");
if (cookieStart == -1) {
cookieStart = cookieValue.indexOf(cookieName + "=");
}
if (cookieStart == -1) {
cookieValue = null;
} else {
cookieStart = cookieValue.indexOf("=", cookieStart) + 1;
var cookieEnd = cookieValue.indexOf(";", cookieStart);
if (cookieEnd == -1) {
cookieEnd = cookieValue.length;
}
cookieValue = unescape(cookieValue.substring(cookieStart, cookieEnd));
}
return cookieValue;
}
Your Facelet would then use the cookie's value if it exists:
<h:outputText value="#{bean.time}">
<f:convertDateTime
dateStyle="full"
timeStyle="full"
type="both"
timeZone="#{cookie.timezoneCookie.value}">
</f:convertDateTime>
</h:outputText>
You may want to try jsTimezoneDetect to detect timezone on the client side and send to the server.
UPDATE: to get a user's Locale, you can try the following:
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
Locale locale = request.getLocale();
Returns an Enumeration of Locale objects indicating, in decreasing
order starting with the preferred locale, the locales that are
acceptable to the client based on the Accept-Language header. If the
client request doesn't provide an Accept-Language header, this method
returns an Enumeration containing one Locale, the default locale for
the server.
If all you need is to display time stamps with the users local time you dont need the Locale object (you need to add the users hours offset to GMT + 0 time), Y
You need to send the value of timezone.offset() (from the example in the link) to the server (you can do it by using servlet post with parameter)
and then add this offset to the date object created on your server (set your locale on the server to be GMT + 00)
that way you will create time stamps with the correct time of the user that is logged into your web app
(that's what I did myself...)
You can also use it like this direct in JSF code:
<script type="text/javascript">
$(document).ready(function () {
var timezone = jstz.determine_timezone();
$("#timezone_holder").val(timezone.name()); //use TimeZone name instead of offset
$("#timezone_holder").change();
});
</script>
Then you can reuse the timezonename in a JSF converter:
<f:convertDateTime pattern="dd.MM.yyyy HH:mm" timeZone="#{bean.timezone}" />