7

Hi guys we have a problem with DST (Daylight Saving time)

We show the time in a Visual Force interface according to the time zone of the logged in user.

However in the Salesforce objects we are storing the time in GMT. We did this because this will support the display even after users change the timezone settings. Also schedule context will run as System and will take system timezone when running. (Not users time zone).

But now the problem is it'll run according to the GMT time not the local time. That is why user had the problem for Brussels timezone.

EG:

When scheduled before 28-Oct-2012

Schedule time in local (Brussels) - 15:00 Schedule time in GMT - 13.00

When running before 28-Oct-2012 Schedule time in local (Brussels) - 15:00 Schedule time in GMT - 13.00

When running after 28-Oct-2012 Schedule time in local (Brussels) - 14:00 Schedule time in GMT - 13.00

I can't think of an logic to support this. Any idea?

  • So you're principally concerned with scheduled apex ? It seems like the case for a custom scheduler, which runs every 15-30 minutes, checks your custom schedule table, works out the GMT Equivalent of the Scheduled Record based on the Locale of the User who created it, and execute it if its time. – techtrekker Oct 31 '12 at 11:44
  • Thank you so much for providing this code! I have been struggling to find the right way to allow someone entering a date into sf to adjust it based on the timezone the event they are creating will be held in. This looks like it will work perfectly in my application. Thank you for sharing!! – user2494 Mar 5 '13 at 16:44
7

So I've written logic to calculate timezone offsets as an adaptation of some Apex code I found online.

This was for a similar problem where I was calling out with a date/time to webservice that was expecting GMT and was reconverting the values that SFDC was sending after they arrived assuming they were GMT (while I was still using a standard SFDC component).

It took a while, and you might want to modify it, but it includes European timezones.

This isn't a complete set, but is based on the TZ_database on wikipedia.

Hopefully this gets you going in the right direction as far as setting your dates/times.

To use, input the target timezone you want the offset from GMT for, and than you can add that value back to your time input value in hours to get the correct offset for time based on daylight savings time

     public static Integer getTZOffset(String targetTimezone) {

      Map<String, Integer[]> tzSIDKeys = getTZSidKeys();

      Date[] dstDatesNow = getDSTDates(System.Today().year());
      Integer UsersTZOffset = 0;

      if (tzSIDKeys.get(targetTimezone) != null) {
         if (System.Today() >= dstDatesNow[0] && System.Today() <= dstDatesNow[1]) UsersTZOffset = tzSIDKeys.get(targetTimezone)[1];
         else UsersTZOffset = tzSIDKeys.get(targetTimezone)[0];
      }
      return UsersTZOffset;
      }

        /* -------------------------------------------------------------------------------------
       * Returns a date Collection of Start/End dates for US Daylight Saving Time
       * for the specified year.
       *
       * Based on code from: http://www.webexhibits.org/daylightsaving/b2.html
       * ------------------------------------------------------------------------------------- */

     public static Date[] getDSTDates(Integer theYear) {
          Long thisYear;
          Long AprilDate;
          Long OctoberDate;
          Long MarchDate;
          Long NovemberDate;
          Long longSeven = 7;
          thisYear = Math.round(theYear);

      AprilDate = Math.mod(2+6 * thisYear - Math.floor(thisYear / 4).longValue(), longSeven) + 1;
      OctoberDate=  Math.mod(31-( Math.floor(thisYear * 5 / 4).longValue() + 1), longSeven);

      MarchDate = 14 - Math.mod(Math.floor(1 + thisYear * 5 / 4).LongValue(), longSeven);
      NovemberDate = 7 - Math.mod(Math.floor (1 + thisYear * 5 / 4).LongValue(), longSeven);

      string startDate = (thisYear > 2006 ? ('03/'+MarchDate) : ('04/'+AprilDate)) + '/' + thisYear;
      string endDate = (thisYear > 2006 ? ('11/'+NovemberDate):('10/'+OctoberDate))+ '/' + thisYear;

      Date[] rtnDates = new List<Date>();
      rtnDates.add(Date.parse(startDate));
      rtnDates.add(Date.parse(endDate));
      return rtnDates;
   }

   public static Map<String, Integer[]> getTZSidKeys() {
      Map<String, Integer[]> tzSIDKeys = new Map<String, Integer[]>();
      tzSIDKeys.put('America/Adak', new Integer[]{-10, -9});
      tzSIDKeys.put('America/Anchorage', new Integer[]{-9, -8});
      tzSIDKeys.put('America/Anguilla', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Antigua', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Araguaina', new Integer[]{-3, -3});// 5

      tzSIDKeys.put('America/Argentina/Buenos_Aires', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Catamarca', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/ComodRivadavia', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Cordoba', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Jujuy', new Integer[]{-3, -3}); //10

      tzSIDKeys.put('America/Argentina/La_Rioja', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Mendoza', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Rio_Gallegos', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Salta', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/San_Juan', new Integer[]{-3, -3}); //15

      tzSIDKeys.put('America/Argentina/San_Luis', new Integer[]{-3, -3}); 
      tzSIDKeys.put('America/Argentina/Tucuman', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Argentina/Ushuaia', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Aruba', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Asuncion', new Integer[]{-4, -3}); //20


      tzSIDKeys.put('America/Atikokan', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Atka', new Integer[]{-10, -9});
      tzSIDKeys.put('America/Bahia', new Integer[]{-3, -2});
      tzSIDKeys.put('America/Bahia_Banderas', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Barbados', new Integer[]{-4, -4}); //25

      tzSIDKeys.put('America/Belem', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Belize', new Integer[]{-6, -6});
      tzSIDKeys.put('America/Blanc-Sablon', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Boa_Vista', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Bogota', new Integer[]{-5, -5});

      tzSIDKeys.put('America/Boise', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Buenos_Aires', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Cambridge_Bay', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Campo_Grande', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Cancun', new Integer[]{-6, -5});

    //  tzSIDKeys.put('America/Caracas', new Integer[]{-4.5, -4.5});
      tzSIDKeys.put('America/Catamarca', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Cayenne', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Cayman', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Chicago', new Integer[]{-6, -5});

      tzSIDKeys.put('America/Chihuahua', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Coral_Harbour', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Cordoba', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Costa_Rica', new Integer[]{-6, -6});
      tzSIDKeys.put('America/Creston', new Integer[]{-7, -7});

      tzSIDKeys.put('America/Cuiaba', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Curacao', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Danmarkshavn', new Integer[]{0, 0});
      tzSIDKeys.put('America/Dawson', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Dawson_Creek', new Integer[]{-7, -7});

      tzSIDKeys.put('America/Denver', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Detroit', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Dominica', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Edmonton', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Eirunepe', new Integer[]{-4, -4});

      tzSIDKeys.put('America/El_Salvador', new Integer[]{-6, -6});
      tzSIDKeys.put('America/Ensenada', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Fort_Wayne', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Fortaleza', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Glace_Bay', new Integer[]{-4, -3});

      tzSIDKeys.put('America/Godthab', new Integer[]{-3, -2});
      tzSIDKeys.put('America/Goose_Bay', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Grand_Turk', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Grenada', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Guadeloupe', new Integer[]{-4, -4});

      tzSIDKeys.put('America/Guayaquil', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Guyana', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Halifax', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Havana', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Hermosillo', new Integer[]{-7, -7});

      tzSIDKeys.put('America/Indiana/Indianapolis', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indiana/Knox', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Indiana/Marengo', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indiana/Petersburg', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indiana/Tell_City', new Integer[]{-6, -5});

      tzSIDKeys.put('America/Indiana/Vevay', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indiana/Vincennes', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indiana/Winamac', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Indianapolis', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Inuvik', new Integer[]{-7, -6});

      tzSIDKeys.put('America/Iqaluit', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Jamaica', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Jujuy', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Juneau', new Integer[]{-9, -8});
      tzSIDKeys.put('America/Kentucky/Louisville', new Integer[]{-5, -4});

      tzSIDKeys.put('America/Kentucky/Monticello', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Knox_IN', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Kralendijk', new Integer[]{-4, -4});
      tzSIDKeys.put('America/La_Paz', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Lima', new Integer[]{-5, -5});

      tzSIDKeys.put('America/Los_Angeles', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Louisville', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Lower_Princes', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Maceio', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Managua', new Integer[]{-6, -6});

      tzSIDKeys.put('America/Manaus', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Marigot', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Martinique', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Matamoros', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Mazatlan', new Integer[]{-7, -6});

      tzSIDKeys.put('America/Mendoza', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Menominee', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Merida', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Metlakatla', new Integer[]{-8, -8});
      tzSIDKeys.put('America/Mexico_City', new Integer[]{-6, -5});

      tzSIDKeys.put('America/Miquelon', new Integer[]{-3, -2});
      tzSIDKeys.put('America/Moncton', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Monterrey', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Montevideo', new Integer[]{-3, -2});
      tzSIDKeys.put('America/Montreal', new Integer[]{-5, -4});

      tzSIDKeys.put('America/Montserrat', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Nassau', new Integer[]{-5, -4});
      tzSIDKeys.put('America/New_York', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Nipigon', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Nome', new Integer[]{-9, -8});

      tzSIDKeys.put('America/Noronha', new Integer[]{-2, -2});
      tzSIDKeys.put('America/North_Dakota/Beulah', new Integer[]{-6, -5});
      tzSIDKeys.put('America/North_Dakota/Center', new Integer[]{-6, -5});
      tzSIDKeys.put('America/North_Dakota/New_Salem', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Ojinaga', new Integer[]{-7, -6});

      tzSIDKeys.put('America/Panama', new Integer[]{-5, -5});
      tzSIDKeys.put('America/Pangnirtung', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Paramaribo', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Phoenix', new Integer[]{-7, -7});
      tzSIDKeys.put('America/Port_of_Spain', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Port-au-Prince', new Integer[]{-5, -4});

      tzSIDKeys.put('America/Porto_Acre', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Porto_Velho', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Puerto_Rico', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Rainy_River', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Rankin_Inlet', new Integer[]{-6, -5});

      tzSIDKeys.put('America/Recife', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Regina', new Integer[]{-6, -6});
      tzSIDKeys.put('America/Resolute', new Integer[]{-6, -5});
      tzSIDKeys.put('America/Rio_Branco', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Rosario', new Integer[]{-3, -3});

      tzSIDKeys.put('America/Santa_Isabel', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Santarem', new Integer[]{-3, -3});
      tzSIDKeys.put('America/Santiago', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Santo_Domingo', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Sao_Paulo', new Integer[]{-3, -2});

      tzSIDKeys.put('America/Scoresbysund', new Integer[]{-1, 0});
      tzSIDKeys.put('America/Shiprock', new Integer[]{-7, -6});
      tzSIDKeys.put('America/Sitka', new Integer[]{-9, -8});
      tzSIDKeys.put('America/St_Barthelemy', new Integer[]{-4, -4});
      //tzSIDKeys.put('America/St_Johns', new Integer[]{-3.5, -2.5});

      tzSIDKeys.put('America/St_Kitts', new Integer[]{-4, -4});
      tzSIDKeys.put('America/St_Lucia', new Integer[]{-4, -4});
      tzSIDKeys.put('America/St_Thomas', new Integer[]{-4, -4});
      tzSIDKeys.put('America/St_Vincent', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Swift_Current', new Integer[]{-6, -6});

      tzSIDKeys.put('America/Tegucigalpa', new Integer[]{-6, -6});
      tzSIDKeys.put('America/Thule', new Integer[]{-4, -3});
      tzSIDKeys.put('America/Thunder_Bay', new Integer[]{-5, -4});
      tzSIDKeys.put('America/Tijuana', new Integer[]{-8,-7});
      tzSIDKeys.put('America/Toronto', new Integer[]{-5, -4});

      tzSIDKeys.put('America/Tortola', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Vancouver', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Virgin', new Integer[]{-4, -4});
      tzSIDKeys.put('America/Whitehorse', new Integer[]{-8, -7});
      tzSIDKeys.put('America/Winnipeg', new Integer[]{-6, -5}); 
      tzSIDKeys.put('America/Yakutat', new Integer[]{-9, -8});     
      tzSIDKeys.put('America/Yellowknife', new Integer[]{-7, -6});

      tzSIDKeys.put('Europe/Amsterdam', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Andorra', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Athens', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Belfast', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Belgrade', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Bratislava', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Brussels', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Bucharest', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Budapest', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Chisinau', new Integer[]{2, 3});

      tzSIDKeys.put('Europe/Copenhagen', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Dublin', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Gibraltar', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Guernsey', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Helsinki', new Integer[]{2, 3});

      tzSIDKeys.put('Europe/Isle_of_Man', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Istanbul', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Jersey', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Kaliningrad', new Integer[]{3, 3});
      tzSIDKeys.put('Europe/Kiev', new Integer[]{2, 3});

      tzSIDKeys.put('Europe/Lisbon', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Ljubljana', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/London', new Integer[]{0, 1});
      tzSIDKeys.put('Europe/Luxembourg', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Kaliningrad', new Integer[]{3, 3});

      tzSIDKeys.put('Europe/Madrid', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Malta', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Mariehamn', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Minsk', new Integer[]{3, 3});
      tzSIDKeys.put('Europe/Monaco', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Moscow', new Integer[]{4, 4});
      tzSIDKeys.put('Europe/Nicosia', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Oslo', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Paris', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Podgorica', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Prague', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Prague', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Rome', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Samara', new Integer[]{4, 4});
      tzSIDKeys.put('Europe/San_Marino', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Sarajevo', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Simferopol', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Skopje', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Sofia', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Stockholm', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Tallinn', new Integer[]{2, 3});

      tzSIDKeys.put('Europe/Tirane', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Tiraspol', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Uzhgorod', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Vaduz', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Vatican', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Vienna', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Vilnius', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Volgograd', new Integer[]{4, 4});
      tzSIDKeys.put('Europe/Warsaw', new Integer[]{1, 2});
      tzSIDKeys.put('Europe/Zagreb', new Integer[]{1, 2});

      tzSIDKeys.put('Europe/Zaporozhye', new Integer[]{2, 3});
      tzSIDKeys.put('Europe/Zurich', new Integer[]{1, 2});

      return tzSIDKeys;
   }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.