<!DOCTYPE html>
<html>
  <head>
    <link data-require="bootstrap@*" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
    <script data-require="angular.js@*" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
    <script data-require="angular-strap@*" data-semver="2.1.3" src="//cdn.rawgit.com/mgcrea/angular-strap/v2.1.3/dist/angular-strap.js"></script>
    <script data-require="angular-strap@*" data-semver="2.1.3" src="//cdn.rawgit.com/mgcrea/angular-strap/master/dist/angular-strap.tpl.js"></script>
    <script data-require="moment.js@*" data-semver="2.8.3" src="http://momentjs.com/downloads/moment.js"></script>
    <script data-require="moment-timezone-with-data@*" data-semver="0.2.5" src="http://momentjs.com/downloads/moment-timezone-with-data.js"></script>
    <script data-require="angular-resource@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular-resource.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="ngMoment.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="myApp" ng-controller="dataCtrl"> 
    <h1>Angular Strap picker in timezone!</h1>
    
    <select ng-options="zone as zone for zone in data.zonesToChoose" ng-model="data.timezone" ng-change="reloadPicker()"></select>
    <div> {{ data.txt }}</div>
    <div>Timezone IANA: {{ data.timezone }}</div>
    <div>Original UTC date: {{ data.dateTimeUtc }}</div>
    <div>Date in timezone: {{ data.dateTimeUtc | ngmDateFormat:'YYYY-MM-DD HH:mm:ss':data.timezone:'utc' }}</div>
    <div class="form-group">
        <label class="control-label"><i class="fa fa-calendar"></i> Datetime picker</label><br>
        <div class="row">
          <div class="col-xs-3">
            <input type="text" size="10" class="form-control" ng-model="data.pickerDateTime" data-autoclose="1" placeholder="Date" bs-datepicker ng-change="pickerChange()">
            </div>
            <div class="col-xs-3">
            <input type="text" size="8" class="form-control" ng-model="data.pickerDateTime" data-autoclose="1" placeholder="Time" bs-timepicker ng-change="pickerChange()">
            </div>
        </div>
    </div>
    
  </body>

</html>
// Code goes here
(function(){
  'use strict';
  
  var myApp = angular.module('myApp', ['ngMoment', 'mgcrea.ngStrap']);
  
  myApp.config(['$datepickerProvider', function ($datepickerProvider) {
        angular.extend($datepickerProvider.defaults, {
            dateFormat: 'dd/MM/yyyy',
            startWeek: 1
        });
    }]);
    
    myApp.config(['$timepickerProvider', function ($timepickerProvider) {
        angular.extend($timepickerProvider.defaults, {
            timeFormat: 'HH:mm',
            length: 7
        });
    }]); 

  myApp.controller('dataCtrl', function ($scope, $http, ngmTimeCalc) {
     $http.get('data.json').then(function(result){
        $scope.data = result.data;
        $scope.data.zonesToChoose = moment.tz.names(); 
        $scope.txt = JSON.stringify($scope.data.zonesToChoose);
        $scope.reloadPicker();
        
    });
    
    $scope.pickerChange = function () {
        $scope.data.dateTimeUtc = ngmTimeCalc.convertFromPicker(
          $scope.data.pickerDateTime, $scope.data.timezone);
    }
    
    $scope.reloadPicker=function(){
      $scope.data.pickerDateTime = ngmTimeCalc.convertToPicker(
        $scope.data.dateTimeUtc, $scope.data.timezone);
    }
    
    
  });
  
}());

/* Styles go here */

{
  "dateTimeUtc":"2015:03:28T12:42:00Z",
  "timezone":"Europe/Warsaw"
}
/*global angular define require module*/

'format global';

'deps angular';
'deps moment';

(function () {

    'use strict';

    function ngMoment(angular, moment) {
        return angular.module('ngMoment', [])
            .constant('ngMomentConfig', {
                preprocess: null, // e.g. 'unix', 'utc', ...
                timezone: '',
                format: null,
                statefulFilters: true
            })
            .constant('moment', moment)
            .factory('ngmTimeCalc', ['$log', 'moment', 'ngMomentConfig', function ($log, moment, ngMomentConfig) {
                var preprocessors = {
                    utc: moment.utc,
                    unix: moment.unix
                };
                
                // ReSharper disable FunctionsUsedBeforeDeclared
                var service = {
                    convertToPicker: convertToPicker,
                    convertFromPicker: convertFromPicker,
                    returnLocalOffset: returnLocalOffset,
                    returnTimeZoneOffset: returnTimeZoneOffset,
                    addDays: addDays,
                    preprocessDate: preprocessDate,
                    applyTimezone: applyTimezone
                };

                return service;

                //*****************************
                

                function convertToPicker(dateTime, dateTimeZone) {
                    var localOffset = returnLocalOffset();
                    var timeZoneOffset = returnTimeZoneOffset(dateTimeZone);
                    var result;
                    var mdt;
                    var tmpDate;
                    if (typeof dateTime === 'string') {
                        var preprocessedValue = preprocessDate(dateTime, 'utc', 'YYYY-MM-DDTHH:mm:ss');
                        tmpDate = moment(preprocessedValue);
                    }
                    else if (Object.prototype.toString.call(dateTime) === '[object Date]') {
                        tmpDate = moment(dateTime);
                    } else {
                        tmpDate = moment(dateTime);
                    }

                    mdt = tmpDate.subtract(localOffset, 'm').add(timeZoneOffset, 'm');
                    result = mdt.toDate();
                    return result;
                }

                function convertFromPicker(dateTime, dateTimeZone) {
                    var localOffset = returnLocalOffset();
                    var timeZoneOffset = returnTimeZoneOffset(dateTimeZone);
                    var result;
                    var mdt;
                    var tmpDate;
                    if (typeof dateTime === 'string') {
                        var preprocessedValue = preprocessDate(dateTime, 'utc', 'YYYY-MM-DDTHH:mm:ss');
                        tmpDate = moment(preprocessedValue);
                    }
                    else if (Object.prototype.toString.call(dateTime) === '[object Date]') {
                        tmpDate = moment(dateTime);
                    } else {
                        tmpDate = moment(dateTime);
                    }

                    mdt = tmpDate.add(localOffset, 'm').subtract(timeZoneOffset, 'm');
                    result = mdt.toDate();
                    return result;
                }

                function returnLocalOffset() {
                    var result = moment().utcOffset();
                    return result;
                }

                function returnTimeZoneOffset(dateTimeZone) {
                    var result = moment.tz(dateTimeZone).utcOffset();
                    return result;
                }

                function addDays(dateTime, days) {
                    var result = moment(dateTime).add(days, 'd').toDate();
                    return result;
                }

                function preprocessDate(value, preprocess, format) {
                    if (angular.isUndefined(preprocess)) {
                        preprocess = ngMomentConfig.preprocess;
                    }
                    if (preprocessors[preprocess]) {
                        return preprocessors[preprocess](value, format);
                    }
                    if (preprocess) {
                        $log.warn('ngMoment: Ignoring unsupported value for preprocess: ' + preprocess);
                    }
                    if (!isNaN(parseFloat(value)) && isFinite(value)) {
                        // Milliseconds since the epoch
                        return moment(parseInt(value, 10));
                    }
                    // else just returns the value as-is.
                    return moment(value, format);
                }

                function applyTimezone(aMoment, tzone) {
                    var timezone = tzone || ngMomentConfig.timezone;
                    if (aMoment && timezone) {
                        if (aMoment.tz) {
                            aMoment = aMoment.tz(timezone);
                        } else {
                            $log.warn('ngMoment: timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?');
                        }
                    } 
                    return aMoment; 
                } 
            }])
            .filter('ngmDateFormat', ['moment', 'ngmTimeCalc', 'ngMomentConfig', 
                function (moment, ngmTimeCalc, ngMomentConfig) {
                    function ngmDateFormatFilter(value, format, timezone, preprocess) {
                        if (typeof value === 'undefined' || value === null) {
                            return '';
                        } 
                        
                        var date;
                        var preprocessedValue;
                        if (typeof value === 'string') {
                          preprocessedValue = ngmTimeCalc.preprocessDate(value, preprocess,'YYYY-MM-DDTHH:mm:ss');
                          date = moment(preprocessedValue);
                          if (!date.isValid()) {
                            return '';
                          }
                        }
                        else if (Object.prototype.toString.call(value) === '[object Date]') {
                          preprocessedValue = ngmTimeCalc.preprocessDate(value, preprocess);
                          date = moment(preprocessedValue);
                        }

                        var timeZoneOffset = ngmTimeCalc.returnTimeZoneOffset(timezone);
                        var result = moment(date).add(timeZoneOffset, 'm').format(format);
                        return result;
                    }

                    ngmDateFormatFilter.$stateful = false;

                    return ngmDateFormatFilter;
                }]);
    }

    if (typeof define === 'function' && define.amd) {
        define(['angular', 'moment'], ngMoment);
    } else if (typeof module !== 'undefined' && module && module.exports) {
        ngMoment(angular, require('moment'));
    } else {
        ngMoment(angular, window.moment);
    }

}());