离子时区选择器

时间:2015-10-07 20:58:43

标签: angularjs timezone ionic-framework ionic

我正在尝试在我的Ionic项目中实现时区选择器,我遇到了一些问题。更具体一点,时区选择器将用于用户的编辑个人资料页面。此时区非常重要,因为我的应用程序允许用户签入(例如Untappd)他们当前正在尝试的项目。我希望签到日期与他们的时区相匹配。

我被困的地方:由于所提供的图书馆种类繁多,我有点困惑。我没有运气实施我找到的解决方案。我对使用这个学位的时区也有点新意,所以另一个问题是,我应该允许用户更改他们的GMT偏移吗?或者现在通常只是自动检测这个?

我遇到了以下几个库,但如上所述,我在Angular / Ionic项目中实现这些并没有任何好运。 (参见下面的代码片段。)

找到的图书馆

我的实施:

index.html (我意识到这太过分了,但是试图让它们中的任何一个起作用。)

<!-- moment/timezone -->
<script src="lib/timezone-js/src/date.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.js"></script>
<script src="lib/angular-tz-extensions/lib/angular-tz-extensions.min.js"></script>
<script src="lib/moment/min/moment.min.js"></script>
<script src="lib/angular-moment/angular-moment.min.js"></script>
<script src="lib/moment-timezone/moment-timezone.js"></script>
<script src="lib/moment-timezone/moment-timezone-utils.js"></script>

app.js

angular.module('curdcollective', [
  'ionic',
  'ionic.service.core',
  'ionic.service.deploy',
  'ionic.service.analytics',
  'ionic.service.push',
  'ngIOS9UIWebViewPatch',
  [...](Removed for brevity),
  'Timezones'
])

.constant(
  '$timezones.definitions.location',
  '/lib/angular-tz-extensions/tz/data'
)

我不明白$timezones是如何可用的,但这就是docs say

profile_edit.html (这就是我想要的。)

<label class="item item-input item-select">
    <div class="input-label">Timezone</div>
    <select name="data[User][timezone]" ng-model="item.User.timezone">
        <option ng-repeat="zone in zones by zone.name" ng-value="zone.abbr">{{zone}}</option>
    </select>
</label>
<label class="item item-input item-select">
    <div class="input-label">GMT Offset</div>
    <select name="data[User][gmt_offset]" ng-model="item.User.gmt_offset">
        <option ng-repeat="offset in offsets" ng-value="offset">{{offset}}</option>
    </select>
</label>

controllers.js

/**
 * ProfileController
 * Methods related to the user profile.
 */
.controller('ProfileController', function($state, $scope, $ionicHistory, $ionicPopup, $timezones, angularMomentConfig, $ionicModal, $stateParams, $resource, $sanitize, AuthService, LoadingService, ApiService, Me, $cordovaSocialSharing, BucketService) {

  //Resolve a timezone
  // var scope.timezone = $timezone.resolve('America/New_York', new Date());
  // console.log(scope.timezone);

  //Apply the timezone when a new one is selected
  //from the edit profile view.
  this.applyTimezone = function ($timezone) {
    angularMomentConfig.preprocess = 'utc';
    angularMomentConfig.timezone = $timezone.getName();
    console.log(angularMomentConfig.timezone);
  };

  //@url https://github.com/chouseknecht/angular-tz-extensions
  $timezones.getZoneList($scope);
  $scope.$on('zonesReady', function(zones){
    $scope.zones = zones;
    console.log($scope.zones);
  });

  [...](Removed code for brevity.)

  $scope.getTimeZonesList = function(moment){
    console.log('getTimeZonesList');
    var rZones = angular.forEach(moment.tz.zones(), function (zone) {
      return {
        name: zone.displayName,
        abbr: moment.tz(zone.displayName).zoneAbbr()
      };
    });
    console.log(rZones);
    return rZones;
  };


  // Create the login modal that we will use later
  $ionicModal.fromTemplateUrl('templates/profile_edit.html', {
    scope: $scope
  }).then(function(modal) {
    $scope.editModal = modal;
  });
  //
  $scope.showEditProfile = function(){
    $scope.editModal.show();
  };
  $scope.hideEditProfile = function(){
    $scope.editModal.hide();
  };
})

1 个答案:

答案 0 :(得分:2)

我最终制作了以下Angular Timezone服务。它不完美,它可以使用一些优化,我仍然可以使用如何使其更好的建议。

如果用户尚未使用Timezone.detect()设置时区,我会自动检测。

这是实际的选择代码:

<select name="data[User][timezone]" ng-model="item.User.timezone" ng-options="zone.name for zone in zones" selected="item.User.timezone">
   <option value="">Select Timezone</option>
</select>

请参阅https://gist.github.com/robksawyer/98df7bb13d5efeac5dde上的要点。

/**
 * Bower dependencies:
 * timezone-js
 * moment
 * moment-timezone
 * angular-moment
 * angular-tz-extensions
 *
 * index.html:
 * <script src="lib/timezone-js/src/date.js"></script>
 * <script src="http://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.js"></script>
 * <script src="lib/moment/min/moment-with-locales.min.js"></script>
 * <script src="lib/moment-timezone/builds/moment-timezone-with-data.min.js"></script>
 * <script src="lib/moment-timezone/moment-timezone-utils.js"></script>
 * <script src="lib/angular-moment/angular-moment.min.js"></script>
 * <script src="lib/angular-tz-extensions/lib/angular-tz-extensions.min.js"></script>
 */
angular.module('curdcollective.services', [
    'angularMoment', 'Timezones'
])

/**
 * TimezoneService
 * Helper for Timezone related things
 * @url https://github.com/chouseknecht/angular-tz-extensions
 * @url https://github.com/urish/angular-moment
 * @url http://momentjs.com/timezone/
 */
.service('TimezoneService', function(moment, $timezones, $filter, angularMomentConfig) {

    //Get a list of timezones (via moment-timezone)
    var timezones = [];

    var autoDetectedTimezone = $timezones.getLocal() || 'UTC';

    function pad(value) {
        return value < 10 ? '0' + value : value;
    }

    function setDefaults(timezone){
        if(!this.autoDetectedTimezone && !timezone){
            return 'You need to detect the timezone first.';
        }
        //Set the default timezone
        moment.tz.setDefault(this.autoDetectedTimezone);
        angularMomentConfig.timezone = this.autoDetectedTimezone;
    }

    return {

        //
        //Initializes the timezone methods and loads required variables
        //
        initTimezones: function(){
            this.timezones = [];
            angular.forEach(moment.tz.names(), function (zone, key) {
                this.push({
                    name: zone,
                    abbr: moment.tz(zone).zoneAbbr(),
                    offset: moment.tz(zone).format('Z')
                });
            }, this.timezones);
        },

        getTimezoneOffset: function(tz){
            if(!tz){
                tz = this.autoDetectedTimezone;
            }
            var rightNow = new Date();
            var tzAlign = $timezones.align(rightNow, tz);
            return tzAlign.getTimezoneOffset();
        },

        getHours: function(tz){
            if(!tz){
                tz = this.autoDetectedTimezone;
            }
            var rightNow = new Date();
            var tzAlign = $timezones.align(rightNow, tz);
            return tzAlign.getHours();
        },

        getGMTOffset: function(tz){
            if(!tz){
                tz = this.autoDetectedTimezone;
            }
            var rightNow = new Date();
            var tzAlign = $timezones.align(rightNow, tz);
            return $filter('date')(tzAlign,'Z');
        },

        //See https://github.com/chouseknecht/angular-tz-extensions
        getLocale: function(tz){
            if(!tz){
                tz = this.autoDetectedTimezone;
            }
            return tz.locality;
        },

        //Handles setting the default timezone for the app.
        setDefaults: function(timezone){
            if(!this.autoDetectedTimezone && !timezone){
                return 'You need to detect the timezone first.';
            }
            //Set the default timezone
            moment.tz.setDefault(this.autoDetectedTimezone);
            angularMomentConfig.timezone = this.autoDetectedTimezone;
        },

        //Handles auto-detecting the user's timezone
        detect: function(){
            this.autoDetectedTimezone = $timezones.getLocal() || 'UTC';
            setDefaults(this.autoDetectedTimezone.name);
            return this.autoDetectedTimezone.name;
        },

        //Retrieves a list of all timezones known
        getTimezones: function(){
            return this.timezones;
        },

        //DEPRECATED
        /*createOffset: function(date) {
            var sign = (date.getTimezoneOffset() > 0) ? '-' : '+';
            var offset = Math.abs(date.getTimezoneOffset());
            var hours = pad(Math.floor(offset / 60));
            var minutes = pad(offset % 60);
            return sign + hours + ':' + minutes;
        }*/
    };
});