I'm going to share what I've learned from building my own calendar application. Some of this will seem obvious or common-knowledge, but I want to make sure the subject is covered thoroughly and I also want to make sure that everyone who is interested in the subject will be on the same page.
My goal: to develop what I call a "movable calendar" - a set of date/time services that will operate correctly no matter what time zone or locale the user is in. *** The concept - OFBiz uses java.sql.Timestamp for storing/retrieving date/time values. Timestamp is a long data type that contains milliseconds elapsed since Jan 1, 1970. The time is referenced to UTC. A particular moment in time that is represented by a Timestamp value can be thought of as a constant, or that the value is immutable. The user's timezone or locale does not alter the Timestamp's value. In order for a user to interact with a Timezone value in a way that reflects their timezone and locale, the Timezone value must be converted to a user-friendly data type - typically a String. Java supplies a good set of classes that manage Timestamp-to-String and String-to-Timestamp conversions. Those classes do all the work of basing the conversions on timezones and locales - the programmer doesn't have to bother with any of those details. As long as the services that handle date/time values always utilize the user's timezone and locale in conversions, then the goal will be achieved - a calendar that moves with the user. It helps to look at it this way: Entity --> Conversion to String using the user's time zone and locale --> UI UI --> Conversion to Timestamp using the user's time zone and locale --> Entity It is very important to understand that all conversions must be run through the same services, otherwise the date/time value presented to the user (or stored in an entity) will be unpredictable. *** The implementation - I created two conversion methods: public static String timeStampToString(Timestamp stamp, TimeZone tz, Locale locale); public static Timestamp stringToTimeStamp(String dateTimeString, TimeZone tz, Locale locale); and I made sure that all date/time data in my calendar application is routed through those two methods. The implementation was successful. A date/time value I create in one timezone appears in the correct time when I switch timezones. In addition, since the conversions utilize the user's locale, the date/time values are displayed/edited in the format I expect to see them (dd mmm yyyy if I'm in Europe). *** Building out the basic implementation - When I first mentioned I was working on a calendar application, a few developers suggested I just use the WorkEffort component. I took a close look at it and decided against that approach because it had one major flaw - all date/time values are based on the server's timezone and locale. So, any calendar based on WorkEffort will not be movable. Plus, it would be much faster for me to develop one from scratch instead of reverse engineering WorkEffort and fixing its flaws. I'll describe my approach here in order to share the lessons I learned - I am NOT trying to push my calendar application on the community. My hope is the lessons I learned can be applied to the existing code base. I looked at the various existing entities and came up with a very fundamental data structure that many of them share. The field names that the existing entities use may be different, but they all have the same purpose. I called the basic structure a Timed Event: <entity entity-name="TimedEvent" package-name="org.ofbiz.calendar" title="Timed Event"> <field name="eventId" type="id-ne"></field> <field name="parentEventId" type="id"></field> <field name="eventType" type="id-ne"></field> <field name="eventStatus" type="id"></field> <field name="description" type="description"></field> <field name="startDateTime" type="date-time"></field> <field name="endDateTime" type="date-time"></field> <field name="recurringId" type="id"></field> <prim-key field="eventId"/> <relation type="one" rel-entity-name="Enumeration"> <key-map field-name="eventType" rel-field-name="enumId"/> </relation> </entity> Then I built a set of CRUD services around it. All of the services accept a time zone ID and locale as parameters and they run all conversions through the two conversion methods I created. Here's where I ran into my first problem - I took the shortcut approach in my services.xml file: <service name="createTimedEvent" engine="java" location="org.ofbiz.calendar.EventCalendarServices" invoke="createTimedEvent"> <description>Create a Timed Event</description> <auto-attributes entity-name="TimedEvent" include="nonpk" mode="IN" optional="true"/> <attribute name="tzId" type="String" mode="IN" optional="true"/> <attribute name="eventId" type="String" mode="OUT" optional="true"/> </service> When the createTimedEvent service is invoked with String data types, startDateTime and endDateTime arrive in the Java code as Timestamp data types. How nice - the service engine converted the strings to Timestamps for me. Normally I would be appreciative, but the problem is, the service engine did the conversions based upon the server's timezone and locale - not the user's. That is not acceptable. So, I had to remove the auto-attributes entry and list the startDateTime and endDateTime attributes as Strings. Next, I created my Calendar Event entity by specifying a few additional event properties and relating that entity to TimedEvent. On to the user interface. I prefer to develop with the bsh/ftl combo - it's flexible and intuitive for me. That's where I ran into my next problem. Ftl transforms like ${timedEvent.startDateTime} - if startDateTime is a Timestamp data type - are converted to Strings by Freemarker using the server's timezone and locale. So, every date/time value that appears on the screen had to be converted to Strings BEFORE hitting the template. One Freemarker transform is okay to use: ${timedEvent.startDateTime?string("#")} - which converts the Timestamp object to its milliseconds value. As I mentioned previously, that value is a constant that isn't altered by timezone or locale. Having jumped those hurdles, I had a working "movable" calendar. If I switch timezones, the calendar events move to the correct slots. If I switch to a French locale, the week starts on Monday. Date/time values are displayed and editied in locale-appropriate formats. It all works flawlessly. *** Applying this information to OFBiz - There have been a number of Jira issues submitted that revolve around date/time issues. My hope is those issues can be revisited with this information and possibly find solutions to the problems. The UtilDateTime class was created before the new Calendar and Timezone Java classes, so many of its methods are based on the server's timezone and locale. An updated UtilDateTime class has been submitted to Jira (https://issues.apache.org/jira/browse/OFBIZ-2) and I am in the process of testing it now. By the way, I am in no way suggesting that EVERY date/time piece of data needs to be converted. Some date/time values make better sense if they are referenced to the server's timezone and locale. Each application needs to be evaluated to determine which style of date/time data to use - the server's or the user's. -Adrian |
Hi Adrian,
Could you please share the code and files, which is the same issue i am facing... i need to change the dateformat of the entire application to dd-MM-yyyy Please help me to solve my issue. Waiting for your reply. Thanks, Naveen Chanda
|
That email is very old. Since it was written, the framework and Work
Effort application have been improved to support user-selected locale and time zone. -Adrian naveenchanda wrote: > Hi Adrian, > > Could you please share the code and files, which is the same issue i am > facing... i need to change the dateformat of the entire application to > dd-MM-yyyy > > Please help me to solve my issue. > > Waiting for your reply. > > Thanks, > Naveen Chanda > > > > > Adrian Crum wrote: >> I'm going to share what I've learned from building my own calendar >> application. Some of this will seem obvious or common-knowledge, but I >> want to make sure the subject is covered thoroughly and I also want to >> make sure that everyone who is interested in the subject will be on the >> same page. >> >> My goal: to develop what I call a "movable calendar" - a set of date/time >> services that will operate correctly no matter what time zone or locale >> the user is in. >> >> *** The concept - >> >> OFBiz uses java.sql.Timestamp for storing/retrieving date/time values. >> Timestamp is a long data type that contains milliseconds elapsed since Jan >> 1, 1970. The time is referenced to UTC. A particular moment in time that >> is represented by a Timestamp value can be thought of as a constant, or >> that the >> value is immutable. The user's timezone or locale does not alter the >> Timestamp's value. >> >> In order for a user to interact with a Timezone value in a way that >> reflects their timezone and locale, the Timezone value must be converted >> to a user-friendly data type - typically a String. Java supplies a good >> set of classes that manage Timestamp-to-String and String-to-Timestamp >> conversions. >> Those classes do all the work of basing the conversions on timezones and >> locales - the programmer doesn't have to bother with any of those details. >> >> As long as the services that handle date/time values always utilize the >> user's timezone and locale in conversions, then the goal will be achieved >> - a calendar that moves with the user. It helps to look at it this way: >> >> Entity --> Conversion to String using the user's time zone and locale --> >> UI >> UI --> Conversion to Timestamp using the user's time zone and locale --> >> Entity >> >> It is very important to understand that all conversions must be run >> through the same services, otherwise the date/time value presented to the >> user (or stored in an entity) will be unpredictable. >> >> *** The implementation - >> >> I created two conversion methods: >> >> public static String timeStampToString(Timestamp stamp, TimeZone tz, >> Locale locale); >> public static Timestamp stringToTimeStamp(String dateTimeString, >> TimeZone tz, Locale locale); >> >> and I made sure that all date/time data in my calendar application is >> routed through those two methods. The implementation was successful. A >> date/time value I create in one timezone appears in the correct time when >> I switch timezones. In addition, since the conversions utilize the user's >> locale, the >> date/time values are displayed/edited in the format I expect to see them >> (dd mmm yyyy if I'm in Europe). >> >> *** Building out the basic implementation - >> >> When I first mentioned I was working on a calendar application, a few >> developers suggested I just use the WorkEffort component. I took a close >> look at it and decided against that approach because it had one major flaw >> - all date/time values are based on the server's timezone and locale. So, >> any >> calendar based on WorkEffort will not be movable. Plus, it would be much >> faster for me to develop one from scratch instead of reverse engineering >> WorkEffort and fixing its flaws. I'll describe my approach here in order >> to share the lessons I learned - I am NOT trying to push my calendar >> application >> on the community. My hope is the lessons I learned can be applied to the >> existing code base. >> >> I looked at the various existing entities and came up with a very >> fundamental data structure that many of them share. The field names that >> the existing entities use may be different, but they all have the same >> purpose. I called the basic structure a Timed Event: >> >> >> <entity entity-name="TimedEvent" package-name="org.ofbiz.calendar" >> title="Timed Event"> >> <field name="eventId" type="id-ne"></field> >> <field name="parentEventId" type="id"></field> >> <field name="eventType" type="id-ne"></field> >> <field name="eventStatus" type="id"></field> >> <field name="description" type="description"></field> >> <field name="startDateTime" type="date-time"></field> >> <field name="endDateTime" type="date-time"></field> >> <field name="recurringId" type="id"></field> >> <prim-key field="eventId"/> >> <relation type="one" rel-entity-name="Enumeration"> >> <key-map field-name="eventType" rel-field-name="enumId"/> >> </relation> >> </entity> >> >> Then I built a set of CRUD services around it. All of the services accept >> a time zone ID and locale as parameters and they run all conversions >> through the two conversion methods I created. Here's where I ran into my >> first problem - I took the shortcut approach in my services.xml file: >> >> <service name="createTimedEvent" engine="java" >> location="org.ofbiz.calendar.EventCalendarServices" >> invoke="createTimedEvent"> >> <description>Create a Timed Event</description> >> <auto-attributes entity-name="TimedEvent" include="nonpk" mode="IN" >> optional="true"/> >> <attribute name="tzId" type="String" mode="IN" optional="true"/> >> <attribute name="eventId" type="String" mode="OUT" optional="true"/> >> </service> >> >> When the createTimedEvent service is invoked with String data types, >> startDateTime and endDateTime arrive in the Java code as Timestamp data >> types. How nice - the service engine converted the strings to Timestamps >> for me. Normally I would be appreciative, but the problem is, the service >> engine did >> the conversions based upon the server's timezone and locale - not the >> user's. That is not acceptable. So, I had to remove the auto-attributes >> entry and list the startDateTime and endDateTime attributes as Strings. >> >> Next, I created my Calendar Event entity by specifying a few additional >> event properties and relating that entity to TimedEvent. >> >> On to the user interface. I prefer to develop with the bsh/ftl combo - >> it's flexible and intuitive for me. That's where I ran into my next >> problem. Ftl transforms like ${timedEvent.startDateTime} - if >> startDateTime is a Timestamp data type - are converted to Strings by >> Freemarker using the server's >> timezone and locale. So, every date/time value that appears on the screen >> had to be converted to Strings BEFORE hitting the template. One Freemarker >> transform is okay to use: ${timedEvent.startDateTime?string("#")} - which >> converts the Timestamp object to its milliseconds value. As I mentioned >> previously, that value is a constant that isn't altered by timezone or >> locale. >> >> Having jumped those hurdles, I had a working "movable" calendar. If I >> switch timezones, the calendar events move to the correct slots. If I >> switch to a French locale, the week starts on Monday. Date/time values are >> displayed and editied in locale-appropriate formats. It all works >> flawlessly. >> >> *** Applying this information to OFBiz - >> >> There have been a number of Jira issues submitted that revolve around >> date/time issues. My hope is those issues can be revisited with this >> information and possibly find solutions to the problems. >> >> The UtilDateTime class was created before the new Calendar and Timezone >> Java classes, so many of its methods are based on the server's timezone >> and locale. An updated UtilDateTime class has been submitted to Jira >> (https://issues.apache.org/jira/browse/OFBIZ-2) and I am in the process of >> testing it now. >> >> By the way, I am in no way suggesting that EVERY date/time piece of data >> needs to be converted. Some date/time values make better sense if they are >> referenced to the server's timezone and locale. Each application needs to >> be evaluated to determine which style of date/time data to use - the >> server's >> or the user's. >> >> -Adrian >> >> >> > |
Hi Adrian,
As i am very new to the OFBiz, i cannot able to locate the Timezone settings for the format of dd-MM-yyyy and also the locale settings for Indonesia. Please help me to solve my above task. Thanks, Naveen Chanda
|
Naveen,
The current OFBiz framework supports a user-selected locale and time zone. There are places in the UI where those settings are ignored and date/time strings are hard-coded to the yyyy-MM-dd HH:mm:ss.SSS format. That was a design decision made by the developer community. Most of the framework code uses a formatting string constant found in UtilDateTime.java: public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; If you want to change the date/time format, that would be place to do it. It would be best to have those format strings loaded from a properties file, so that users like yourself can change it easily - without having to modify framework code. Anyone wanting to work on that improvement can submit a patch to Jira and I would be happy to review and commit it. -Adrian naveenchanda wrote: > Hi Adrian, > > As i am very new to the OFBiz, i cannot able to locate the Timezone settings > for the format of dd-MM-yyyy and also the locale settings for Indonesia. > > > Please help me to solve my above task. > > > Thanks, > Naveen Chanda > > > > > Adrian Crum wrote: >> That email is very old. Since it was written, the framework and Work >> Effort application have been improved to support user-selected locale >> and time zone. >> >> -Adrian >> >> naveenchanda wrote: >>> Hi Adrian, >>> >>> Could you please share the code and files, which is the same issue i am >>> facing... i need to change the dateformat of the entire application to >>> dd-MM-yyyy >>> >>> Please help me to solve my issue. >>> >>> Waiting for your reply. >>> >>> Thanks, >>> Naveen Chanda >>> >>> >>> >>> >>> Adrian Crum wrote: >>>> I'm going to share what I've learned from building my own calendar >>>> application. Some of this will seem obvious or common-knowledge, but I >>>> want to make sure the subject is covered thoroughly and I also want to >>>> make sure that everyone who is interested in the subject will be on the >>>> same page. >>>> >>>> My goal: to develop what I call a "movable calendar" - a set of >>>> date/time >>>> services that will operate correctly no matter what time zone or locale >>>> the user is in. >>>> >>>> *** The concept - >>>> >>>> OFBiz uses java.sql.Timestamp for storing/retrieving date/time values. >>>> Timestamp is a long data type that contains milliseconds elapsed since >>>> Jan >>>> 1, 1970. The time is referenced to UTC. A particular moment in time that >>>> is represented by a Timestamp value can be thought of as a constant, or >>>> that the >>>> value is immutable. The user's timezone or locale does not alter the >>>> Timestamp's value. >>>> >>>> In order for a user to interact with a Timezone value in a way that >>>> reflects their timezone and locale, the Timezone value must be converted >>>> to a user-friendly data type - typically a String. Java supplies a good >>>> set of classes that manage Timestamp-to-String and String-to-Timestamp >>>> conversions. >>>> Those classes do all the work of basing the conversions on timezones and >>>> locales - the programmer doesn't have to bother with any of those >>>> details. >>>> >>>> As long as the services that handle date/time values always utilize the >>>> user's timezone and locale in conversions, then the goal will be >>>> achieved >>>> - a calendar that moves with the user. It helps to look at it this way: >>>> >>>> Entity --> Conversion to String using the user's time zone and locale >>>> --> >>>> UI >>>> UI --> Conversion to Timestamp using the user's time zone and locale --> >>>> Entity >>>> >>>> It is very important to understand that all conversions must be run >>>> through the same services, otherwise the date/time value presented to >>>> the >>>> user (or stored in an entity) will be unpredictable. >>>> >>>> *** The implementation - >>>> >>>> I created two conversion methods: >>>> >>>> public static String timeStampToString(Timestamp stamp, TimeZone >>>> tz, >>>> Locale locale); >>>> public static Timestamp stringToTimeStamp(String dateTimeString, >>>> TimeZone tz, Locale locale); >>>> >>>> and I made sure that all date/time data in my calendar application is >>>> routed through those two methods. The implementation was successful. A >>>> date/time value I create in one timezone appears in the correct time >>>> when >>>> I switch timezones. In addition, since the conversions utilize the >>>> user's >>>> locale, the >>>> date/time values are displayed/edited in the format I expect to see them >>>> (dd mmm yyyy if I'm in Europe). |
Bump.
--- On Wed, 10/14/09, Adrian Crum <[hidden email]> wrote: > From: Adrian Crum <[hidden email]> > Subject: Re: Dates, Times, Timezones, Locales, and OFBiz > To: [hidden email], "[hidden email]" <[hidden email]> > Date: Wednesday, October 14, 2009, 1:24 PM > Naveen, > > The current OFBiz framework supports a user-selected locale > and time > zone. There are places in the UI where those settings are > ignored and > date/time strings are hard-coded to the yyyy-MM-dd > HH:mm:ss.SSS format. > That was a design decision made by the developer > community. > > Most of the framework code uses a formatting string > constant found in > UtilDateTime.java: > > public static final String DATE_TIME_FORMAT = "yyyy-MM-dd > HH:mm:ss.SSS"; > > If you want to change the date/time format, that would be > place to do it. > > It would be best to have those format strings loaded from a > properties > file, so that users like yourself can change it easily - > without having > to modify framework code. Anyone wanting to work on that > improvement can > submit a patch to Jira and I would be happy to review and > commit it. > > -Adrian > > > naveenchanda wrote: > > Hi Adrian, > > > > As i am very new to the OFBiz, i cannot able to locate > the Timezone settings > > for the format of dd-MM-yyyy and also the locale > settings for Indonesia. > > > > > > Please help me to solve my above task. > > > > > > Thanks, > > Naveen Chanda > > > > > > > > > > Adrian Crum wrote: > >> That email is very old. Since it was written, the > framework and Work > >> Effort application have been improved to support > user-selected locale > >> and time zone. > >> > >> -Adrian > >> > >> naveenchanda wrote: > >>> Hi Adrian, > >>> > >>> Could you please share the code and files, > which is the same issue i am > >>> facing... i need to change the dateformat of > the entire application to > >>> dd-MM-yyyy > >>> > >>> Please help me to solve my issue. > >>> > >>> Waiting for your reply. > >>> > >>> Thanks, > >>> Naveen Chanda > >>> > >>> > >>> > >>> > >>> Adrian Crum wrote: > >>>> I'm going to share what I've learned from > building my own calendar > >>>> application. Some of this will seem > obvious or common-knowledge, but I > >>>> want to make sure the subject is covered > thoroughly and I also want to > >>>> make sure that everyone who is interested > in the subject will be on the > >>>> same page. > >>>> > >>>> My goal: to develop what I call a "movable > calendar" - a set of > >>>> date/time > >>>> services that will operate correctly no > matter what time zone or locale > >>>> the user is in. > >>>> > >>>> *** The concept - > >>>> > >>>> OFBiz uses java.sql.Timestamp for > storing/retrieving date/time values. > >>>> Timestamp is a long data type that > contains milliseconds elapsed since > >>>> Jan > >>>> 1, 1970. The time is referenced to UTC. A > particular moment in time that > >>>> is represented by a Timestamp value can be > thought of as a constant, or > >>>> that the > >>>> value is immutable. The user's timezone or > locale does not alter the > >>>> Timestamp's value. > >>>> > >>>> In order for a user to interact with a > Timezone value in a way that > >>>> reflects their timezone and locale, the > Timezone value must be converted > >>>> to a user-friendly data type - typically a > String. Java supplies a good > >>>> set of classes that manage > Timestamp-to-String and String-to-Timestamp > >>>> conversions. > >>>> Those classes do all the work of basing > the conversions on timezones and > >>>> locales - the programmer doesn't have to > bother with any of those > >>>> details. > >>>> > >>>> As long as the services that handle > date/time values always utilize the > >>>> user's timezone and locale in conversions, > then the goal will be > >>>> achieved > >>>> - a calendar that moves with the user. It > helps to look at it this way: > >>>> > >>>> Entity --> Conversion to String using > the user's time zone and locale > >>>> --> > >>>> UI > >>>> UI --> Conversion to Timestamp using > the user's time zone and locale --> > >>>> Entity > >>>> > >>>> It is very important to understand that > all conversions must be run > >>>> through the same services, otherwise the > date/time value presented to > >>>> the > >>>> user (or stored in an entity) will be > unpredictable. > >>>> > >>>> *** The implementation - > >>>> > >>>> I created two conversion methods: > >>>> > >>>> public static String > timeStampToString(Timestamp stamp, TimeZone > >>>> tz, > >>>> Locale locale); > >>>> public static > Timestamp stringToTimeStamp(String dateTimeString, > >>>> TimeZone tz, Locale locale); > >>>> > >>>> and I made sure that all date/time data in > my calendar application is > >>>> routed through those two methods. The > implementation was successful. A > >>>> date/time value I create in one timezone > appears in the correct time > >>>> when > >>>> I switch timezones. In addition, since the > conversions utilize the > >>>> user's > >>>> locale, the > >>>> date/time values are displayed/edited in > the format I expect to see them > >>>> (dd mmm yyyy if I'm in Europe). > > |
Free forum by Nabble | Edit this page |