title: How to format java.util.Date with DateTimeFormatter portable?
body: <p>How to format <code>java.util.Date</code> with <code>DateTimeFormatter</code> portable?</p>
  
  <p>I can't use </p>
  
  <pre><code>Date in = readMyDateFrom3rdPartySource();
  LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
  ldt.format(dateTimeFormatter);
  </code></pre>
  
  <p>because I afraid that usage of <code>ZoneId.systemDefault()</code> can introduce some changes.</p>
  
  <p>I need to format exactly that object I have.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Note: time is time. Not space. Timezone is very rough measure of longitude, i.e. space. I don't need it. Only time (and date).</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I wrote the following program, proving, that <code>Date</code> DOES NOT only contain correct "instant":</p>
  
  <pre><code>import java.text.ParseException;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  
  public class DataNature2 {
  
     public static void main(String[] args) throws ParseException {
  
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  
        String dateTimeString = "1970-01-01 00:00:01";
  
        Date date = simpleDateFormat.parse(dateTimeString);
  
        System.out.println("1 second = " + date.getTime());
  
     }
  }
  </code></pre>
  
  <p>The output is follows:</p>
  
  <pre><code>1 second = -10799000
  </code></pre>
  
  <p>While it should be</p>
  
  <pre><code>1 second = 1000
  </code></pre>
  
  <p>if <code>Date</code> was "Instant".</p>
  
  <p>The number <code>10799000</code> is <code>3*60*60*1000-1000</code> - the timezone offset of my local time.</p>
  
  <p>This means, that <code>Date</code> class is dual. It's millisecond part may be shifted relatively to <code>hh mm ss</code> part by timezone offset.</p>
  
  <p>This means, that if any utility returns <code>Date</code> object in terms of it's parts (<code>hh mm ss</code>) then it implicitly converted to local time. And <code>getTime()</code> means DIFFERENT time simultaneously. I mean on different machines if this program run at the same time, <code>getTime()</code> will be the same, while time parts will be different.</p>
  
  <p>So, the code example in the beginning is correct: it takes "instant" part of <code>Date</code>, and supplies system timezone part, which was implicitly used inside <code>Date</code>. I.e. it converts dual <code>Date</code> object into explicit <code>LocalDateTime</code> object with the same parts. And hence, formatting after that, is correct.</p>
  
  <p><strong>UPDATE 3</strong></p>
  
  <p>Event funnier:</p>
  
  <pre><code>Date date = new Date(70, 0, 1, 0, 0, 1);
  assertEquals(1000, date.getTime());
  </code></pre>
  
  <p>this test fails.</p>
  
  <p><strong>UDPATE 4</strong></p>
  
  <p>New code. Dedicated to all believers.</p>
  
  <pre><code>public class DataNature3 {
  
     public static class TZ extends java.util.TimeZone {
  
  
        private int offsetMillis;
  
        public TZ(int offsetHours) {
           this.offsetMillis = offsetHours * 60 * 60 * 1000;
        }
  
        @Override
        public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {
           throw new UnsupportedOperationException();
        }
  
        @Override
        public void setRawOffset(int offsetMillis) {
           this.offsetMillis = offsetMillis;
        }
  
        @Override
        public int getRawOffset() {
           return offsetMillis;
        }
  
        @Override
        public boolean useDaylightTime() {
           return false;
        }
  
        @Override
        public boolean inDaylightTime(Date date) {
           return false;
        }
     }
  
     public static void main(String[] args) {
  
        Date date = new Date(0);
  
        for(int i=0; i&lt;10; ++i) {
  
           TimeZone.setDefault(new TZ(i));
  
           if( i&lt;5 ) {
              System.out.println("I am date, I am an instant, I am immutable, my hours property is " + date.getHours() + ", Amen!");
           }
           else {
              System.out.println("WTF!? My hours property is now " + date.getHours() + " and changing! But I AM AN INSTANT! I AM IMMUTABLE!");
           }
  
        }
  
        System.out.println("Oh, please, don't do that, this is deprecated!");
  
     }
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>I am date, I am an instant, I am immutable, my hours property is 0, Amen!
  I am date, I am an instant, I am immutable, my hours property is 1, Amen!
  I am date, I am an instant, I am immutable, my hours property is 2, Amen!
  I am date, I am an instant, I am immutable, my hours property is 3, Amen!
  I am date, I am an instant, I am immutable, my hours property is 4, Amen!
  WTF!? My hours property is now 5 and changing! But I AM AN INSTANT! I AM IMMUTABLE!
  WTF!? My hours property is now 6 and changing! But I AM AN INSTANT! I AM IMMUTABLE!
  WTF!? My hours property is now 7 and changing! But I AM AN INSTANT! I AM IMMUTABLE!
  WTF!? My hours property is now 8 and changing! But I AM AN INSTANT! I AM IMMUTABLE!
  WTF!? My hours property is now 9 and changing! But I AM AN INSTANT! I AM IMMUTABLE!
  Oh, please, don't do that, this is deprecated!
  </code></pre>