title: Convert to local time zone from latitude and longitude R
body: <p>I have one data frame with a lot of locations (around 30.000), and I need to convert the time of each location for the local time.
  I tried some ideas like <a href="https://stackoverflow.com/questions/23414340/convert-to-local-time-zone-using-latitude-and-longitude">this one</a>, and <a href="https://stackoverflow.com/questions/48408507/get-the-local-time-from-a-utc-time?noredirect=1&amp;lq=1">this one</a>. But they did not work for me.</p>
  
  <p>I have data like this:</p>
  
  <pre><code>dt = data.table(date = c("2018-01-16 22:02:37",
                           "2018-01-16 22:54:00", 
                           "2018-01-16 23:08:38"),
                  lat = c(-54.5010,
                          -54.5246,
                          -54.5285),
                  long = c(-25.0433, 
                           -25.0929,
                           -25.0832))
  </code></pre>
  
  <p>And I expected this output:</p>
  
  <pre><code>date                      lat           long
  2018-01-16 20:02:37       -54.5010      -25.0433
  2018-01-16 20:54:00       -54.5246      -25.0929
  2018-01-16 21:08:38       -54.5285      -25.0832
  </code></pre>
  
  <p>One try:</p>
  
  <pre><code>library(sf)
  dt = data.table(date = c("2018-01-16 22:02:37",
                           "2018-01-16 22:54:00", 
                           "2018-01-16 23:08:38"),
                  lat = c(-54.5010,
                          -54.5246,
                          -54.5285),
                  long = c(-25.0433, 
                           -25.0929,
                           -25.0832))
  
  sdf = st_as_sf(dt, coords = c("long", "lat"), crs = 4326)
  
  ## import timezones (after extraction) and intersect with spatial points
  tzs = st_read("timezones.geojson/combined.json", quiet = TRUE) #HERE DONT WORK
  sdf = st_join(sdf, tzs)
  
  ## convert timestamps to local time
  sdf$timeL = as.POSIXlt(sdf$time1, tz = as.character(sdf$tzid))
  sdf$timeL
  </code></pre>
  
  <pre><code>Cannot open data source timezones.geojson/combined.json
  
  Error in CPL_read_ogr(dsn, layer, query, as.character(options), quiet,  :
    Open failed.
  </code></pre>
  
  <p>Then I tried:</p>
  
  <pre><code>library(lutz)
  library(sf)
  library(purrr)
  library(dplyr)
  
  download.file("https://github.com/evansiroky/timezone-boundary-builder/releases/download/2019a/timezones-with-oceans.geojson.zip",
                destfile = "tz.zip")
  unzip("tz.zip", exdir = "data-raw/dist/")
  tz_full &lt;- read_sf("data-raw/dist/combined-with-oceans.json")
  </code></pre>
  
  <p>But this didn't work either.</p>
  
  <pre><code>Cannot open data source ~/Dropbox/Érika Project/mestrado_R/bhv_loc_R/tables/data-raw/dist/combined-with-oceans.json
  Error in CPL_read_ogr(dsn, layer, query, as.character(options), quiet,  : 
    Open failed.
  </code></pre>
  
  <p>I got it just like this:</p>
  
  <pre><code>library(lutz)
  
  v &lt;- tz_lookup_coords(lat = dt$lat, lon = dt$lon, method = "accurate")
  v1&lt;-as.data.frame(v)
  </code></pre>
  
  <p>The output:</p>
  
  <pre><code>[1] "America/Bahia" "Etc/GMT+3"     "Etc/GMT+3"     "Etc/GMT+3"     "Etc/GMT+3"     "Etc/GMT+3"   
  </code></pre>
  
  <p>But with this output I dont know how can I convert the timezones.</p>
  
  <p>I thought in do something like this:</p>
  
  <pre><code>v1$tzone &lt;- NA
  v1[v1$v == "America/Bahia", "tzone"] &lt;- "+3" 
  v1[v1$v == "America/Sao_Paulo", "tzone"] &lt;- "+3" 
  v1[v1$v == "Etc/GMT+2", "tzone"] &lt;- "+2" 
  v1[v1$v == "Etc/GMT+3", "tzone"] &lt;- "+3" 
  
    if (v1$tzone == "+3" ) {
    v1$timeBR &lt;- NA
    v1$timeBR &lt;- strptime(v1$time, format = "%Y-%m-%d %H:%M:%S")
    v1$timeBR &lt;- v1$timeBR -3*3600 #creating a column corresponding to local Brazilian time (UTC -3)
    v1$hourBR &lt;- as.POSIXlt(v1$timeBR)$hour
    v1 &lt;- v1[!is.na(v1$timeBR),]
    }
  
  #But the function not works (I dont know do functions), would gonna be better one function with the two condition +3 and +2 
  </code></pre>
  
  <p><strong>EDIT</strong></p>
  
  <p>With the suggestion:</p>
  
  <pre><code>&gt; library(data.table)
  data.table 1.12.8 using 2 threads (see ?getDTthreads).  Latest news: r-datatable.com
  Warning message:
  package ‘data.table’ was built under R version 3.5.2 
  &gt; library(lutz)
  Warning message:
  package ‘lutz’ was built under R version 3.5.2 
  &gt; library(purrr)
  
  Attaching package: ‘purrr’
  
  The following object is masked from ‘package:data.table’:
  
      transpose
  
  &gt; library(lubridate)
  
  Attaching package: ‘lubridate’
  
  The following objects are masked from ‘package:data.table’:
  
      hour, isoweek, mday, minute, month, quarter, second, wday, week, yday, year
  
  The following object is masked from ‘package:base’:
  
      date
  
  #t it is the original data
  &gt; head(t$time)
  [1] 2017-10-16 17:01:00 2017-10-16 18:35:22 2017-10-16 20:38:54 2017-10-16 21:27:27 2017-10-16 21:43:20
  [6] 2017-10-16 23:24:46
  27092 Levels: 2016-10-24 15:42:00 2016-10-24 21:03:28 2016-10-24 22:04:35 2016-10-24 23:13:40 ... 2020-01-10 11:34:21
  &gt; class(t$time)
  [1] "factor"
  &gt; date2&lt;-t$time
  &gt; class(date2)
  [1] "factor"
  &gt; date2&lt;- as.character(t$time)
  &gt; class(date2)
  [1] "character"
  &gt; head(date2)
  [1] "2017-10-16 17:01:00" "2017-10-16 18:35:22" "2017-10-16 20:38:54" "2017-10-16 21:27:27" "2017-10-16 21:43:20"
  [6] "2017-10-16 23:24:46"
  &gt; t[, date2 := as.POSIXct(date2, format = "%Y-%m-%d %H:%M:%S", tz = "GMT")][,
  +                                                                          timezone := tz_lookup_coords(lat = lat, lon = long, method = "accurate")][,
  +                                                                                                                                                    new_time := map2(.x = date2, .y = timezone, 
  +                                                                                                                                                                     .f = function(x, y) {with_tz(time = x, tzone = y)})][]
  Error in `:=`(date2, as.POSIXct(date2, format = "%Y-%m-%d %H:%M:%S", tz = "GMT")) : 
    Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").
  </code></pre>
  
  <p><strong>EDIT2</strong></p>
  
  <p><strong>I found what was going wrong, my original data wasn't in data.table and data.frame format!
  Then, now I have this list inside the data. Im trying to convert in one new column</strong></p>
  
  <p><strong>EDIT 3</strong></p>
  
  <p><strong>NOW WORKED! THANKS TO ALL FOR COMMENTS AND HELP</strong></p>
  
  <pre><code>t[, date2 := as.POSIXct(date2, format = "%Y-%m-%d %H:%M:%S", tz = "GMT")]
  [,timezone := tz_lookup_coords(lat = lat, lon = lon, method = "accurate")]
  [,new_time := map2(.x = date2, .y = timezone,
  .f = function(x, y) {with_tz(time = x, tzone = y)})][]
  
  newtime&lt;-do.call(rbind, lapply(t$new_time, as.data.frame))
  t$newtime&lt;-paste(newtime$`X[[i]]`)
  
  head(t$newtime)
  [1] "2016-10-24 12:42:00" "2016-10-24 18:03:28" "2016-10-24 19:04:35" "2016-10-24 20:13:40" "2016-10-24 21:13:00"
  [6] "2016-10-25 02:17:05"
  
  </code></pre>
  
  <p>Someone know how to do this?
  Thanks</p>