5 Replies Latest reply on Dec 26, 2007 4:40 PM by pmuir

    [newbie] timezones and s:convertDateTime

      I want the user to select a timezone and then display a the server systemdate in the users timezone...
      switching the timezone seems to work, but the page will always display the same date, no matter, which timezone I select.

      first I wrote a small stateless bean, to get the available timezones and the current date:

      @Stateless
      @Name("timeZoneUtil")
      public class TimeZoneUtil implements Serializable, TimeZoneUtilInterface {
      
       public List<SelectItem> getTimeZones() {
       String[] timeZoneIDs = java.util.TimeZone.getAvailableIDs();
       List<SelectItem> selectItems = new ArrayList<SelectItem>(
       timeZoneIDs.length);
       for (String name : timeZoneIDs) {
       selectItems.add(new SelectItem(name, name));
       }
       return selectItems;
       }
      
       public Date getCurrentDateTime() {
       return new Date();
       }
      ...
      }
      


      in the webpage, I use the standard seam functions to switch the locale and display the date/time:

       <h:form id="change_tz">
       <h:selectOneMenu value="#{timeZoneSelector.timeZoneId}">
       <f:selectItems value="#{timeZoneUtil.timeZones}"/>
       </h:selectOneMenu>
       <h:commandButton action="#{timeZoneSelector.select}" value="Timezone"/>
       </h:form>
      
       <div>CurrentDateTime:
       timezone: #{timeZoneSelector.timeZone}
       <p>
       <h:outputText value="#{timeZoneUtil.currentDateTime}">
       <s:convertDateTime type="both" dateStyle="full"/>
       </h:outputText>
       </p>
       </div>
      


      Switching the locale seems to work, but the page will always display the same date!?
      e.g.

      CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Etc/GMT+10",offset=-36000000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

      Dienstag, 11. Dezember 2007 16:22:04

      some seconds later:


      CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Etc/GMT+12",offset=-43200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

      Dienstag, 11. Dezember 2007 16:22:39


        • 1. Re: [newbie] timezones and s:convertDateTime

          I just tried to switch the locale of my browser (via a nice firefox plugin: quick locale switcher).
          When I do this, it seems, that convertDateTime displays the correct local time (relative to the selected locale).

          CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Etc/GMT+12",offset=-43200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
          
          Mittwoch, 12. Dezember 2007 00:52:13
          2007-12-12 13:52:13.012


          however: calling timeZoneSelector.select() seems to have no impact on convertDateTime at all.
          any ideas, what I am doing wrong?

          BTW: I'm using seam 2.0.0.GA

          • 2. Re: [newbie] timezones and s:convertDateTime

            after some other hours of trying, changing and debugging, I already know somthing more :-)

            when I change the timezone via the timezone-switcher, the timezone will be set to the new value, BUT at that time the date-time that I display on the page has already been converted (using the "old" timezone) and thus will not reflect the timezone change. when I refresh the page manually again, it is ok (which is of course an unreasonable demand to our webusers..).
            anyway, here is what I think, why this happens:

            when I press the button in my page, a POST request will be sent to the server (the action to execute is of course timezone.select).
            In the phases of the JSF lifecycle, the following will happen:

            • Apply Request Values Phase
              timeZoneSelector.select event is queued (not executed)
            • Process Validations Phase
              s:convertDateTime will call its converter: DateTimeConverter, which will convert the date/time using the current time zone, which is of course still the "old" timezone
            • Update Model Phase
              the converted date/time from the last step is pushed to the model
              the new TimeZone is pushed into model
            • Invoke Application Phase
              the queued event is now executed:
              - from now on the new time zone is active
              - TimeZoneSelector raises "org.jboss.seam.timeZoneSelected" event
            • Render Response Phase
              the page is rendered and the value of my date/time field is still that one calculated in the Process Validations Phase (with the old timezone)
              when I now refresh the page manually, the new timezone is already active and now the DateTimeConverter uses this new timezone and the calculated value will be displayed as expected.

              since I'm a newbie with all that JSF, SEAM, etc. stuff, I appreciate any coments on this..

              following questions that are still open:
              • any ideas for a solution/workaround? how can I avoid that manually refreshing of the page
              • who observes the "org.jboss.seam.timeZoneSelected" event?? I searched through all seam .java files, but couldn't find any observer?


            • 3. Re: [newbie] timezones and s:convertDateTime
              pmuir

              You can observe the event in your code if you want to. I don't really understand why it fails. Put a breakpoint on getCurrentDateTime and see when it is called, and what date is returned.

              • 4. Re: [newbie] timezones and s:convertDateTime

                 


                • call the page 4 the 1st time
                  15:37:02,640 INFO [Contexts] starting up: org.jboss.seam.web.session
                  15:37:02,702 INFO [DebugObserver] JSF phase: before RESTORE_VIEW 1
                  15:37:02,811 INFO [DebugObserver] JSF phase: after RESTORE_VIEW 1
                  15:37:02,858 INFO [DebugObserver] JSF phase: before RENDER_RESPONSE 6
                  breakpoint: org.jboss.seam.ui.converter.DateTimeConverter.getTimeZone()
                  breakpoint: org.jboss.seam.international.initTimeZone()
                  breakpoint: getCurrentDateTime() returns "Tue Dec 18 15:40:40 CET 2007"
                  15:40:50,987 INFO [DebugObserver] JSF phase: after RENDER_RESPONSE 6

                  PAGE:
                  CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,
                  dstSavings=3600000,useDaylight=true,transitions=143,lastRule=
                  java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings
                  =3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,
                  startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,
                  endDayOfWeek=1,endTime=3600000,endTimeMode=2]]

                  Dienstag, 18. Dezember 2007 15:40:40

                  --> I think this is the system timezone which is GMT+1

                • now I change the timezone to Etc/GMT-2 (with raw offset of GMT-02:00)
                  expected output: Dienstag, 18. Dezember 2007 12:40

                  15:42:22,788 INFO [DebugObserver] JSF phase: before RESTORE_VIEW 1
                  breakpoint: org.jboss.seam.ui.converter.DateTimeConverter.getTimeZone()
                  15:43:17,193 INFO [DebugObserver] JSF phase: after RESTORE_VIEW 1
                  15:43:17,224 INFO [DebugObserver] JSF phase: before APPLY_REQUEST_VALUES 2
                  15:43:17,271 INFO [DebugObserver] JSF phase: after APPLY_REQUEST_VALUES 2
                  15:43:17,271 INFO [DebugObserver] JSF phase: before PROCESS_VALIDATIONS 3
                  15:43:17,287 INFO [DebugObserver] JSF phase: after PROCESS_VALIDATIONS 3
                  15:43:17,302 INFO [DebugObserver] JSF phase: before UPDATE_MODEL_VALUES 4
                  breakpoint: org.jboss.seam.international.TimeZoneSelector.setTimeZoneId() id=GMT+2
                  15:44:20,354 INFO [DebugObserver] JSF phase: after UPDATE_MODEL_VALUES 4
                  15:44:20,354 INFO [DebugObserver] JSF phase: before INVOKE_APPLICATION 5
                  15:44:20,370 INFO [DebugObserver] timeZoneSelected Etc/GMT+2
                  15:44:20,370 INFO [DebugObserver] JSF phase: after INVOKE_APPLICATION 5
                  15:44:20,385 INFO [DebugObserver] JSF phase: before RENDER_RESPONSE 6
                  breakpoint: getCurrentDateTime() returns "Tue Dec 18 15:44:20 CET 2007"
                  15:44:44,946 INFO [DebugObserver] JSF phase: after RENDER_RESPONSE 6

                  PAGE:
                  CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Etc/GMT+2",offset=-7200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

                  Dienstag, 18. Dezember 2007 15:44:20
                  --> still the old timezone

                • call another page
                  15:45:52,316 INFO [DebugObserver] JSF phase: before RESTORE_VIEW 1
                  15:45:52,316 INFO [DebugObserver] JSF phase: after RESTORE_VIEW 1
                  15:45:52,331 INFO [DebugObserver] JSF phase: before RENDER_RESPONSE 6
                  15:45:52,987 INFO [DebugObserver] JSF phase: after RENDER_RESPONSE 6

                • then revisit the original page:
                  15:46:22,907 INFO [DebugObserver] JSF phase: before RESTORE_VIEW 1
                  15:46:22,907 INFO [DebugObserver] JSF phase: after RESTORE_VIEW 1
                  15:46:22,923 INFO [DebugObserver] JSF phase: before RENDER_RESPONSE 6
                  breakpoint: org.jboss.seam.ui.converter.DateTimeConverter.getTimeZone()
                  breakpoint: getCurrentDateTime() returns "Tue Dec 18 15:46:49 CET 2007"
                  15:47:06,138 INFO [DebugObserver] JSF phase: after RENDER_RESPONSE 6
                  CurrentDateTime: timezone: sun.util.calendar.ZoneInfo[id="Etc/GMT+2",offset=-7200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

                  Dienstag, 18. Dezember 2007 12:46:49
                  --> now it's correct



                    Maybe it would also help to put a breakpoint somewhere into javax.faces.convert.DateTimeConverter to check when this method is called. But I do not quite know how to do that...
                    I suppose: the seam datetime converter extends javax.faces.convert.DateTimeConverter which must be somewhere in my JSF implementation: somewhere in the facelets.jar
                    but I have just could not find any DateTimeConverter class in the jsf-facelets.jar and I don't know where I can download the facelets source (yet..)


                  • 5. Re: [newbie] timezones and s:convertDateTime
                    pmuir

                    the source will be in the jsf ri download