1 2 Previous Next 20 Replies Latest reply on Feb 17, 2006 12:01 PM by epbernard Go to original post
      • 15. Re: Persistence of Date values depends on default time zone

        Ep, guess why they added overloads of those methods that take a Calendar object. And that is exactly my point. It seems that you are finally starting to understand me.

        • 16. Re: Persistence of Date values depends on default time zone
          maxandersen

          could you please start talking about TIMESTAMP instead of DATE which clearly is not what you should use if it is the UTC time you want to store.

          • 17. Re: Persistence of Date values depends on default time zone
            epbernard

            I understood the problem you described, and answered that the bean to SQL type bridge aka UserType in Hibernate is not the right place to fix it IMO because it needs a user per user (I'm talking browser or rich client) offset operation, because your final users are not on the same timezone.
            Changing everything to get a UTC time out of your jdbc driver will not fix your actual problem from a user point of view.

            Off the debate did you know that we can actually have a minute that is made of 61 or 62 seconds, UTC is pure abhomination for computer systems.

            • 18. Re: Persistence of Date values depends on default time zone

              Ep, apparently you have no experience with writing applications spanning multiple time zones. I have. Your arguments are full of basic mistakes and nonsense (no offense meant). This is not your fault. Everybody was a beginner at some point. But working with time is a complex topic and it has always been a source of confusion. Please take a look here http://www.odi.ch/weblog/posting.php?posting=264 for an introduction. I'll take another approach to explain this to you. I consider it important that you as a Hibernate developer fully understand this.

              The user's point of view is irrelevant in this discussion because:

              When I write an application, most of the time a TZ is not relevant in the business logic. So I can code everything using a Date object. When we need to display a date to a user or need the user to input a date, we always use a DateFormat initialized with the user's TZ. Should we need to perform calculations with dates that actually rely on a certain TZ we use a Calendar initialized with the right TZ. Once again, it is a programming error to assume anything else than GMT/UTC for Date.getTime/setTime. It is unnecessary and impossible to transport information about the user's TZ in a Date instance.

              The user's time zone usually is a local property and has no reason to be stored in the database. I will not talk about the user's TZ here any longer, because it is completely confined to the presentation layer.

              Now when I persist a Date object and retrieve it from the DB on a different server in a different TZ the Date object must still be the same. i.e. the Date object must represent the exact same point in time. There is no reason why information should change on the way to the DB and back!

              Compare this to storing distance information. Store the information "1 mile" in a DB in England and read it in Germany and get back "1.8 km". The distance is still the same, just expressed in different units. Getting back "1 km" in Germany would be wrong.

              Now when I store the information "the meeting starts at 2006-1-1 12h00 GMT" in England and read it in Germany I will get "the meeting starts at 2006-1-1 12h00 GMT+0100" which is "2006-1-1 11h00 GMT" and not the same information anymore.

              But this is what happens! Note the blatant difference to the distance example. In the distance example the actual information does not change. Only the representation is in different units. But in the Date example the actual information changes. Now the people in Germany will arrive one hour too early at the meeting. Note again: The Date class does not assume any units (TZ). So it is nonsense to say "this Date instance is in GMT+0200" or "convert a Date instance to a different TZ". A Date instance is the same everywhere and always denotes the same point in time.

              So where does this confusion come from?
              Popular DBs like Oracle do not store TZ information in DATE columns. But they do use a TZ dependent date format. For simplicity we assume a textual representation. So it is up to the DB user to interprete "2006-1-1 12h00" in the right time zone. This also means that the user is responsible to do a time zone conversion if necessary. The "user" here is the JDBC driver. JDBC offers setDate and getDate methods which accept an additional Calendar object. The Calendar object's TimeZone is used by the JDBC driver to convert the Date object to a DATE column. If no Calendar object is given it uses the VM's default time zone.

              This means when reading and writing Date objects through JDBC you have to make sure to always use the same TZ or you get wrong data. In system that span time zones it is therefore essential that all JDBC calls use the same TZ for JDBC. As their VM default time zone is not the same, the only way to achieve this is by passing a Calendar object to the JDBC setDate/getDate methods. Not doing so will always produce errors and destroy information in the end. The only reasonable "common" time zone is GMT.

              Some databases have TZ information associated with the "DB" and the DB connection. This TZ information may be used to do further conversion in certain cases. But this is completely vendor specific.

              So what is the EJB3 persistence layer doing wrong?
              - It does not pass a well-defined Calendar object to JDBC
              - It doesn't let the user define in which TZ Date objects are stored in the DB
              - It doesn't take into account the vendor specific implementations of the JDBC driver's Date / TZ handling

              Why is this a problem?
              Application developers give the responsibility of persistence to the persistence layer. With it they lose a lot of control about it. In this case the application programmer (me) has no way of fixing the misbehaviour on his side.

              What about Timestamp?
              When you look at the JDBC API you notice that there is no difference in handling Timestamp, Date and Calendar object. They are all converted to a certain time zone when stored in the DB. So it doesn't solve the problem. Timestamp is merely an extension of Date that supports nanoseconds. Nothing more. When you read the API Doc of the Timestamp class you understand why you don't want to use it: It causes problems when comparing it to Date objects.

              • 19. Re: Persistence of Date values depends on default time zone
                christian.bauer

                A classic thread.

                • 20. Re: Persistence of Date values depends on default time zone
                  epbernard

                  I've just tested it. Use
                  @Column(columnDefinition="TIMESTAMP WITH TIME ZONE")

                  Works on Postgres, expected to work on Oracle too.

                  1 2 Previous Next