Index: trunk/lib/App.inc.php
===================================================================
--- trunk/lib/App.inc.php	(revision 738)
+++ trunk/lib/App.inc.php	(revision 739)
@@ -116,5 +116,5 @@
         // Human-readable format used to display dates.
         'date_format' => 'd M Y',
-        'time_format' => 'h:i:s A',
+        'time_format' => 'h:i A',
         'lc_date_format' => '%e %b %Y', // Localized date for strftime() https://www.php.net/manual/en/function.strftime.php
         'lc_time_format' => '%k:%M', // Localized time for strftime() https://www.php.net/manual/en/function.strftime.php
@@ -1839,4 +1839,75 @@
 
     /*
+    * Create a DateTime object from a string and convert its timezone.
+    *
+    * @access   public
+    * @param    string  $datetime   A date-time string or unit timestamp, e.g., `now + 60 days` or `1606165903`.
+    * @param    string  $from_tz    A PHP timezone, e.g., UTC
+    * @param    string  $to_tz      A PHP timezone, e.g., America/Mexico_City
+    * @return   DateTime            A DateTime object ready to use with, e.g., ->format(âŠ).
+    * @author   Quinn Comendant <quinn@strangecode.com>
+    * @since    23 Nov 2020 15:08:45
+    */
+    function convertTZ($datetime, $from_tz, $to_tz)
+    {
+        if (preg_match('/^\d+$/', $datetime)) {
+            // It's a timestamp, format as required by DateTime::__construct().
+            $datetime = "@$datetime";
+        }
+
+        $dt = new DateTime($datetime, new DateTimeZone($from_tz));
+        $dt->setTimezone(new DateTimeZone($to_tz));
+
+        return $dt;
+    }
+
+    /*
+    * Convert a given date-time string from php_timezone to user_timezone, and return formatted.
+    *
+    * @access   public
+    * @param    string  $datetime   A date-time string or unit timestamp, e.g., `now + 60 days` or `1606165903`.
+    * @param    string  $format     A date format string for DateTime->format(âŠ) or strftime(âŠ). Set to lc_date_format by default.
+    * @return   string              A formatted date in the user's timezone.
+    * @author   Quinn Comendant <quinn@strangecode.com>
+    * @since    23 Nov 2020 15:13:26
+    */
+    function dateToUserTZ($datetime, $format=null)
+    {
+        if (empty($datetime) || in_array($datetime, ['0000-00-00 00:00:00', '0000-00-00', '1000-01-01 00:00:00', '1000-01-01'])) {
+            // Zero dates in MySQL should never be displayed.
+            return '';
+        }
+
+        // Create a DateTime object and conver the timezone from server to user.
+        $dt = $this->convertTZ($datetime, $this->getParam('php_timezone'), $this->getParam('user_timezone'));
+
+        // By default, we try to use a localized date format. Set lc_date_format to null to use regular date_format instead.
+        $format = $format ?: $this->getParam('lc_date_format');
+        if ($format && mb_strpos($format, '%') !== false) {
+            // The data format is localized for strftime(). It only accepts a timestamp, which are always in UTC, so we hack this by offering the date from the user's timezone in a format without a TZ specified, which is used to a make a timestamp for strftime (we can't use DaateTime->format('U') because that would convert the date back to UTC).
+            return strftime($format, strtotime($dt->format('Y-m-d H:i:s')));
+        } else {
+            // Otherwise use a regular date format.
+            $format = $format ?: $this->getParam('date_format');
+            return $dt->format($format);
+        }
+    }
+
+    /*
+    * Convert a given date-time string from user_timezone to php_timezone, and formatted as YYYY-MM-DD HH:MM:SS.
+    *
+    * @access   public
+    * @param    string  $datetime   A date-time string or unit timestamp, e.g., `now + 60 days` or `1606165903`.
+    * @param    string  $format     A date format string for DateTime->format(âŠ). Set to 'Y-m-d H:i:s' by default.
+    * @return   string              A formatted date in the server's timezone.
+    * @author   Quinn Comendant <quinn@strangecode.com>
+    * @since    23 Nov 2020 15:13:26
+    */
+    function dateToServerTZ($datetime, $format='Y-m-d H:i:s')
+    {
+        return $this->convertTZ($datetime, $this->getParam('user_timezone'), $this->getParam('php_timezone'))->format($format);
+    }
+
+    /*
     *
     *
