useful when mounting devices (like digital cameras)
                  that are set to UTC in order to avoid the pitfalls of
                  local time.
+time_offset=minutes
+             -- Set offset for conversion of timestamps from local time
+                used by FAT to UTC. I.e. <minutes> minutes will be subtracted
+                from each timestamp to convert it to UTC used internally by
+                Linux. This is useful when time zone set in sys_tz is
+                not the time zone used by the filesystem. Note that this
+                option still does not provide correct time stamps in all
+                cases in presence of DST - time stamps in a different DST
+                setting will be off by one hour.
 
 showexec      -- If set, the execute permission bits of the file will be
                 allowed only if the extension part of the name is .EXE,
 
        unsigned short fs_fmask;
        unsigned short fs_dmask;
        unsigned short codepage;   /* Codepage for shortname conversions */
+       int time_offset;           /* Offset of timestamps from UTC (in minutes) */
        char *iocharset;           /* Charset used for filename input/display */
        unsigned short shortname;  /* flags for shortname display/create rule */
        unsigned char name_check;  /* r = relaxed, n = normal, s = strict */
                 flush:1,          /* write things quickly */
                 nocase:1,         /* Does this need case conversion? 0=need case conversion*/
                 usefree:1,        /* Use free_clusters for FAT32 */
-                tz_utc:1,         /* Filesystem timestamps are in UTC */
+                tz_set:1,         /* Filesystem timestamps' offset set */
                 rodir:1,          /* allow ATTR_RO for directory */
                 discard:1,        /* Issue discard requests on deletions */
                 nfs:1;            /* Do extra work needed for NFS export */
 
        }
        if (opts->flush)
                seq_puts(m, ",flush");
-       if (opts->tz_utc)
-               seq_puts(m, ",tz=UTC");
+       if (opts->tz_set) {
+               if (opts->time_offset)
+                       seq_printf(m, ",time_offset=%d", opts->time_offset);
+               else
+                       seq_puts(m, ",tz=UTC");
+       }
        if (opts->errors == FAT_ERRORS_CONT)
                seq_puts(m, ",errors=continue");
        else if (opts->errors == FAT_ERRORS_PANIC)
        Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
        Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
        Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
-       Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err,
+       Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset,
+       Opt_err,
 };
 
 static const match_table_t fat_tokens = {
        {Opt_immutable, "sys_immutable"},
        {Opt_flush, "flush"},
        {Opt_tz_utc, "tz=UTC"},
+       {Opt_time_offset, "time_offset=%d"},
        {Opt_err_cont, "errors=continue"},
        {Opt_err_panic, "errors=panic"},
        {Opt_err_ro, "errors=remount-ro"},
        opts->utf8 = opts->unicode_xlate = 0;
        opts->numtail = 1;
        opts->usefree = opts->nocase = 0;
-       opts->tz_utc = 0;
+       opts->tz_set = 0;
        opts->nfs = 0;
        opts->errors = FAT_ERRORS_RO;
        *debug = 0;
                case Opt_flush:
                        opts->flush = 1;
                        break;
+               case Opt_time_offset:
+                       if (match_int(&args[0], &option))
+                               return 0;
+                       if (option < -12 * 60 || option > 12 * 60)
+                               return 0;
+                       opts->tz_set = 1;
+                       opts->time_offset = option;
+                       break;
                case Opt_tz_utc:
-                       opts->tz_utc = 1;
+                       opts->tz_set = 1;
+                       opts->time_offset = 0;
                        break;
                case Opt_err_cont:
                        opts->errors = FAT_ERRORS_CONT;
 
                   + days_in_year[month] + day
                   + DAYS_DELTA) * SECS_PER_DAY;
 
-       if (!sbi->options.tz_utc)
+       if (!sbi->options.tz_set)
                second += sys_tz.tz_minuteswest * SECS_PER_MIN;
+       else
+               second -= sbi->options.time_offset * SECS_PER_MIN;
 
        if (time_cs) {
                ts->tv_sec = second + (time_cs / 100);
                       __le16 *time, __le16 *date, u8 *time_cs)
 {
        struct tm tm;
-       time_to_tm(ts->tv_sec, sbi->options.tz_utc ? 0 :
-                  -sys_tz.tz_minuteswest * 60, &tm);
+       time_to_tm(ts->tv_sec,
+                  (sbi->options.tz_set ? sbi->options.time_offset :
+                  -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm);
 
        /*  FAT can only support year between 1980 to 2107 */
        if (tm.tm_year < 1980 - 1900) {