title: Modifying timezone of a POSIXct object without changing the display
body: <p>I have a <code>POSIXct</code> object and would like to change it's <code>tz</code> attribute WITHOUT R to interpret it (interpret it would mean to change how the datetime is displayed on the screen). </p>
  
  <p>Some background: I am using the <code>fasttime</code> package from S.Urbanek, which take strings and cast it to <code>POSIXct</code> very quickly. Problem is that the string should represent a datetime in "GMT" and it's not the case of my data.</p>
  
  <p>I end up with a <code>POSIXct</code> object with <code>tz=GMT</code>, in reality it is <code>tz=GMT+1</code>, if I change the timezone with </p>
  
  <pre><code>attr(datetime, "tzone") &lt;- "Europe/Paris";
  datetime  &lt;- .POSIXct(datetime,tz="Europe/Paris"); 
  </code></pre>
  
  <p>then it will be "displayed" as <code>GMT+2</code> (the underlying value never change).</p>
  
  <p>EDIT: Here is an example</p>
  
  <pre><code>datetime=as.POSIXct("2011-01-01 12:32:23.234",tz="GMT")
  attributes(datetime)
  #$tzone
  #[1] "GMT"
  datetime
  #[1] "2011-01-01 12:32:23.233 GMT"
  </code></pre>
  
  <p>How can I change this attribute without R to interpret it aka how can I change tzone and still have datetime displayed as <code>"2011-01-01 12:32:23.233"</code> ?</p>
  
  <p>EDIT/SOLUTION, @GSee's solution is reasonably fast, lubridate::force_tz very slow</p>
  
  <pre><code>datetime=rep(as.POSIXct("2011-01-01 12:32:23.234",tz="GMT"),1e5)
  f &lt;- function(x,tz) return(as.POSIXct(as.numeric(x), origin="1970-01-01", tz=tz))
  &gt; system.time(datetime2 &lt;- f(datetime,"Europe/Paris"))
     user  system elapsed 
     0.01    0.00    0.02 
  &gt; system.time(datetime3 &lt;- force_tz(datetime,"Europe/Paris"))
     user  system elapsed 
     5.94    0.02    5.98 
  identical(datetime2,datetime3)
  [1] TRUE
  </code></pre>