Getting timezone offset from Google App Engine request headers?
Asked Answered
G

2

6

As per Google App Engine flexible docs, for any incoming request, as a service to the app, App Engine adds the following headers to all requests:

X-AppEngine-Country  as an ISO 3166-1 alpha-2 country code
X-AppEngine-Region    as an ISO-3166-2 standard
X-AppEngine-City
X-AppEngine-CityLatLong
X-Cloud-Trace-Context
X-Forwarded-For: [CLIENT_IP(s)], [global forwarding rule IP]
X-Forwarded-Proto [http | https]

Is there anyway I can get timezone offset using above info from request header using Java?

Gantrisin answered 24/4, 2018 at 15:46 Comment(1)
You could use this? github.com/RomanIakovlev/timeshape convert lat long to timezoneEmeritaemeritus
E
2

Add below to the pom.xml

  <dependency>
    <groupId>net.iakovlev</groupId>
    <artifactId>timeshape</artifactId>
    <version>2018d.1</version>
  </dependency>

And then run below type of code

package taruntest;

import net.iakovlev.timeshape.TimeZoneEngine;

import java.time.ZoneId;
import java.util.Optional;

public class ZoneInfo {
    public static TimeZoneEngine engine = null;
    private static Optional<ZoneId> ZoneID;

    public static void main(String[] args) {
        ZoneID = getZoneIdFromLatLong("12.971599,77.594563");
        System.out.println(ZoneID.toString());
    }

    public static Optional<ZoneId> getZoneIdFromLatLong(String latLong) {
        if (engine == null)
        {
            engine = TimeZoneEngine.initialize();
        }
        String[] latLongArr = latLong.split(",");
        double _lat = Double.parseDouble(latLongArr[0]);
        double _long = Double.parseDouble(latLongArr[1]);

        Optional<ZoneId> maybeZoneId = engine.query(_lat, _long);

        return maybeZoneId;
    }
}

The result is

Optional[Asia/Kolkata]

You can get your current coords using

https://mylocationtest.appspot.com/

Emeritaemeritus answered 27/4, 2018 at 9:2 Comment(4)
net.iakovlev/timeshape is realtively slow to initialize and needs a lot of space to keep the parsed timezone boundary database in memory. Will it work properly in the Google App-Engine environment?Lovelady
Not sure, will need to be deployed and checked. I don't use GAE, so can't test that outEmeritaemeritus
@Lovelady I have tested my solution (other answer) in GAE environment and was working fast.Procora
Author of Timeshape here. The current version of Timeshape (2018d.4) uses roughly 128 MB of heap memory for the whole world, as measured by JOL (openjdk.java.net/projects/code-tools/jol). You can limit this further if you care only about some region of the world by initializing it with a bounding box: TimeZoneEngine.initialize(double minlat, double minlon, double maxlat, double maxlon). As for initialization time, it takes less than 4 seconds on my computer (Intel Core i5-6600). Hope this helps.Cide
W
-1

You can get timezone offset using App Engine flexible headers’ information. Use this code I have created based on App Engine flexible Java quickstart to extract and check the headers information:

 package com.example.appengine.gettingstartedjava.helloworld;

  import java.io.IOException;
  import java.io.PrintWriter;

  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

   // [START example]
  @SuppressWarnings("serial")
  @WebServlet(name = "helloworld", value = "/" )
  public class HelloServlet extends HttpServlet {

      @Override
      public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
      PrintWriter out = resp.getWriter();
     out.println("Hello, world - Flex Servlet");

      String country = req.getHeader("X-AppEngine-Country");
      String region = req.getHeader("X-AppEngine-Region");
      String city = req.getHeader("X-AppEngine-City");
      Float cityLatLong = Float.valueOf(req.getHeader("X-AppEngine-CityLatLong"));   

      out.println("Country: " + country);
      out.println("Region: " + region);
      out.println("City: " + city);
      out.println("CityLatLong: " + cityLatLong);
    } 
  } 
  // [END example]

There is a official Java class to get the timezone once the region is defined: ZonedDateTime. Find an example here that uses it.

ZonedDateTime klDateTime = ldt.atZone(ZoneId.of("Asia/Kuala_Lumpur"));

Notice that you have to transform the headers to a ZoneId legible string, adding the continent before the city. You could read a continent key based on a city type containing them in a Map of List using HashMap, with the continents as keys and the cities in lists, each list assigned to one continent.

Map<String, List<String>> hm = new HashMap<String, List<String>>();

Washin answered 2/5, 2018 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.