cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

Quick-add: + add another resource

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              mixin timeOptions()
  option(value="14") UTC +14
  option(value="13") UTC +13
  option(value="12.75") UTC +12:45
  option(value="12") UTC +12
  option(value="11") UTC +11
  option(value="10.5") UTC +10:30
  option(value="10") UTC +10
  option(value="9.5") UTC +9:30
  option(value="9") UTC +9
  option(value="8.75") UTC +8:45
  option(value="8.5") UTC +8:30
  option(value="8") UTC +8
  option(value="7") UTC +7
  option(value="6.5") UTC +6:30
  option(value="6") UTC +6
  option(value="5:75") UTC +5:45
  option(value="5.5") UTC +5:30
  option(value="5") UTC +5
  option(value="4.5") UTC +4:30
  option(value="4") UTC +4
  option(value="3.5") UTC +3:30
  option(value="3") UTC +3
  option(value="2") UTC +2
  option(value="1") UTC +1
  option(value="0" selected) UTC +0
  option(value="-1") UTC -1
  option(value="-2") UTC -2
  option(value="-3") UTC -3
  option(value="-3.5") UTC -3:30
  option(value="-4") UTC -4
  option(value="-5") UTC -5
  option(value="-6") UTC -6
  option(value="-7") UTC -7
  option(value="-8") UTC -8
  option(value="-9") UTC -9
  option(value="-9.5") UTC -9:30
  option(value="-10") UTC -10
  option(value="-11") UTC -11
  option(value="-12") UTC -12

mixin timeFormatOptions
  option(value="YYYY/M/D H:mm:ss") 2008/5/1 2:00:00
  option(value="ddd, D MMM YYYY HH:mm:ss ZZ") Thu, 1 May 2008 02:00:00 +0900
  option(value="ddd MMM D HH:mm:ss ZZ YYYY") Thu May 1 02:00:00 +0900 2008
  option(value="DDD MMM DD YYYY HH:mm:ss [GMT]ZZ") Thu May 01 2008 02:00:00 GMT+0900
  option(value="X") Unix timestamp
  option(value="x") Unix ms timestamp


.col-xs-12.col-md-4
  .input-field
    h2 input time:

    .col-xs-12.convert-from
      .row
        form.form-inline(onsubmit="return false;")
          .input-group
            span#time-from.input-group-addon
              span.glyphicon.glyphicon-time
            input.form-control#convert-from(type="text", placeholder="input time")
          p.help-block
            a(href="#").now Now
          p.help-block
            | e.g.
            br
            | 2016/12/31 1:23:45
            br
            | 2016, 12, 31 1:23:45 PM
            br
            | Dec 31, 2016 1:23:45
            br
            | 1483115025
            br
            | 1483115025000
      .row
        form.form-inline
          label timezone: 
            select.form-control.input-time-diff
              +timeOptions()
              
.col-xs-12.col-md-6
  .output-field
    h2 result:

    .col-xs-12.convert-to
      .row
        p.result
          //| 2016/11/18(Fri) 21:27:38

      .row
        form.form-inline
          label timezone: 
            select.form-control.output-time-diff
              +timeOptions()

          label format: 
            select.form-control.output-time-format
              +timeFormatOptions()
            
          
!
            
              @use postcss-simple-vars;
@use postcss-nested;


body {
  margin: 20px;
}

.input-field {
  margin-bottom: 40px;
  
  /* clearfix */
  &:after{
    content: '';
    display: block;
    clear: both;
  }
  
  .row:not(:nth-last-of-type(1)) {
    margin-bottom: 10px;
  }
}

.output-field {
  /* clearfix */
  &:after{
    content: '';
    display: block;
    clear: both;
  }
}


h2 {
  color: #ccc;
  font-size: 1em;
}

#convert-from {
  width: 220px !important;
}


.form-inline {
  /* 最後の要素でなければマージンをあける */
  label:not(:nth-last-of-type(1)) {
    margin-right: 1em;
  }
}

/* 出力結果 */
.result {
  font-size: 3em;
}


            
          
!
            
              let mediator = _.extend({}, Backbone.Events);

namespace EVENT {
  SUBMIT: 'submit'
};


class TimeModel extends Backbone.Model {
  
  inputTime: string; // 入力された時間
  inputTimeDiff: number;  // 入力された時間の時差
  inputTimeMoment: Moment;  // inputTimeとinputTimeDiffから生成したMoment←CodePenだと型定義はこれで大丈夫なん??
  outputTime: number; // 出力する時間(ミリ秒)
  outputTimeDiff: number; // 出力する時間の時差
  outputTimeMoment: Moment; // outputTimeとoutputTimeDiffから生成したMoment←CodePenだと型定義はこれで大丈夫なん??
  outputTimeFormat: string|null; // 出力する時間のフォーマット
  isValid: boolean; // 入力された時間が日時のフォーマットになっているか
  
  initialize (attributes?: any, options?: any) {
    _.bindAll(this,
      "updateTime"
    );
    
    this.listenTo(this, "change:inputTime", this.updateTime);
    this.listenTo(this, "change:inputTimeDiff", this.updateTime);
    this.listenTo(this, "change:outputTimeDiff", this.updateTime);
    
    this.updateTime();
    
    // // TEST
    // this.listenTo(this, 'change', function () {
    //   console.log(this.get('inputTime'), this.get('inputTimeDiff'), this.get('outputTimeMoment').format('YYYY/MM/DD HH:mm:ss'), this.get('outputTime'), this.get('outputTimeDiff'));
    // });
  }
  
  defaults() {
    return {
      inputTime: 0,
      isValidDate: true
    }
  }
  
  updateTime(): void {
    const inputTime = this.get('inputTime');
    const inputTimeDiff = this.get('inputTimeDiff');
    var format = '';  // 時刻フォーマット
    
    if (inputTime.match(/^\d{10}$/)) {
      // unix timestamp
      format = 'X';
    }
    else if (inputTime.match(/^\d{13}$/)) {
      // unix ms timestamp
      format = 'x';
    }
    
    // unix timestampの場合utcOffsetが効かない?
    const inputTimeMoment = moment(inputTime, format).utcOffset(inputTimeDiff, 'hours');
    const outputTimeDiff = this.get('outputTimeDiff');
    const outputTimeMoment = inputTimeMoment.utcOffset(outputTimeDiff * 60);
    
    this.set({
      outputTime: parseInt(outputTimeMoment.format('x')),
      outputTimeMoment,
      isValid: outputTimeMoment.isValid()
    });
  }
}



/**
 * 入力フォーム
 *
 */
class InputFormController extends Backbone.View<TimeModel> {

  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onSubmit'
    );
  }
  
  events(): Backbone.EventsHash {
    return {
      "submit form": this.onSubmit
    }
  }
  
  onSubmit (e: Event): void {
    e.preventDefault();
    mediator.trigger(EVENT.SUBMIT);
  }
  
}


class InputFieldView extends Backbone.View<TimeModel> {
  
  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onChangeValid'
    );
    
    this.listenTo(this.model, 'change:isValid', this.onChangeValid);
  }

  onChangeValid (): void {
    if (this.model.get('isValid') === true) {
      this.$el.removeClass('has-error');
    }
    else {
      this.$el.addClass('has-error');
    }
  }
}


/**
 * 時間入力フォーム
 *
 */
class InputTimeController extends Backbone.View<TimeModel> {

  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onChange'
    );
    
    this.listenTo(mediator, EVENT.SUBMIT, this.onChange); // 送信された
  }
  
  events(): Backbone.EventsHash {
    return {
      "change": this.onChange
    }
  }
  
  onChange (): void {
    this.model.set({
      inputTime: this.$el.val()
    });
  }
  
}

/**
 * 時間入力フォーム
 *
 */
class InputTimeView extends Backbone.View<TimeModel> {

  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onUpdate'
    );
    
    this.listenTo(this.model, 'change:inputTime', this.onUpdate);
  }
  
  onUpdate (): void {
    const inputTime = this.model.get('inputTime');
  
    // 入力値とmodelの値に差があった場合、modelの値に合わせる
    if (inputTime !== this.$el.val()) {
      this.$el.val(inputTime);
    }
  }
  
}


class TimeNowController extends Backbone.View<TimeModel> {
  
  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onClick'
    );
  }
  
  events(): Backbone.EventsHash {
    return {
      "click": this.onClick
    }
  }
  
  onClick (e): void {
    e.preventDefault();
    const now = getNow();
    
    this.model.set({
      inputTime: now.time,
      inputTimeDiff: now.diff
    });
  }
}


/**
 * 時差の選択
 *
 */
class TimeDiffController extends Backbone.View<TimeModel> {
  
  target: string; // 'input' or 'output'
  
  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    this.target = options.target;
  
    _.bindAll(this,
      'onChange'
    );
  
    if (this.target === 'input') {    
      this.listenTo(mediator, EVENT.SUBMIT, this.onChange); // 送信された
    }
  }
  
  
  events(): Backbone.EventsHash {
    return {
      "change": this.onChange
    }
  }
  
  onChange (): void {
    const value = parseFloat(this.$el.val());
    
    if (this.target === 'input') {
      this.model.set({
        inputTimeDiff: value
      });
    }
    else if (this.target === 'output') {
      this.model.set({
        outputTimeDiff: value
      });
    }
  }
  
}


/**
 * 時差の選択
 *
 */
class TimeDiffView extends Backbone.View<TimeModel> {
  
  target: string; // 'input' or 'output'
  param: string;  // 対象のmodelの値
  
  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    this.target = options.target;
  
    _.bindAll(this,
      'onUpdate'
    );
  
    let param: string; // listenToする変数名
    if (this.target === 'input') {
      param = 'inputTimeDiff';
    }
    else {
      param = 'outputTimeDiff';
    }

    this.param = param;
    this.listenTo(this.model, `change:${this.param}`, this.onUpdate);
  }
  
  onUpdate (): void {
    const value = this.model.get(this.param);
    
    // 入力値とmodelの値に差があった場合、modelの値に合わせる
    if (parseFloat(this.$el.val()) !== value) {
      this.$el.val(value);
    }
  }
  
}


class OutputTimeView extends Backbone.View<TimeModel> {

  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'render'
    );
    
    this.listenTo(this.model, 'change:outputTime', this.render);
    this.listenTo(this.model, 'change:outputTimeDiff', this.render);
    this.listenTo(this.model, 'change:outputTimeFormat', this.render);
    
    this.render();
  }
  
  render(): void {
    const time = this.model.get('outputTimeMoment')
    const format = this.model.get('outputTimeFormat');
  
    this.$el.html(time.format(format));
  }
  
}


/**
 * 出力時間の形式
 *
 */
class TimeFormatView extends Backbone.View<TimeModel> {
  
  initialize (options?: Backbone.ViewOptions<TimeModel>) {
    _.bindAll(this,
      'onChange'
    );
  }
  
  
  events(): Backbone.EventsHash {
    return {
      "change": this.onChange
    }
  }
  
  onChange (): void {
    this.model.set({
      outputTimeFormat: this.$el.val()
    });
  }
  
}


/**
 * 現在時間と時差を取得
 *
 * @return .time 現在時間
 * @return .diff 時差
 */
function getNow(): string[] {
  const now = new Date();
  const currentTimeZoneOffsetInHours = now.getTimezoneOffset() / -60; // 現在時間の時差
  
  return {
    time: now.toString().replace(/\sGMT[^$]+/i, ''),
    diff: currentTimeZoneOffsetInHours
  };
}


{
  const $convertFrom = $('#convert-from');  // 時間入力フォーム
  const $inputTimeDiff = $('.input-time-diff'); // 入力時間の時差
  const $outputTimDiff = $('.output-time-diff');  // 出力時間の時差
  const $outputTimeFormat = $('.output-time-format');  // 出力時間の形式
  const now = getNow(); // 現在時間と時差
  
  // 入力時間に現在の時間を設定
  $convertFrom.val(now.time);  // GMT〜を削除したローカル時間
  $inputTimeDiff.val(now.diff);
  
  // TODO 入力時間の時差を設定する

  const timeModel = new TimeModel({
    inputTime: $convertFrom.val(),
    inputTimeDiff: parseFloat($inputTimeDiff.val()),
    outputTimeDiff: parseFloat($outputTimDiff.val()),
    outputTimeFormat: $('.output-time-format').val()
  });

  // TODO cookieの設定で、時差、出力後のフォーマットを設定する

  new InputFormController({
    model: timeModel,
    el: '.input-field form'
  });
  
  new InputFieldView({
    model: timeModel,
    el: $('.input-field').find('.input-group').get(0)
  });
  
  new InputTimeController({
    model: timeModel,
    el: $convertFrom.get(0)
  });
  
  new InputTimeView({
    model: timeModel,
    el: $convertFrom.get(0)
  });

  new TimeDiffController({
    model: timeModel,
    el: $inputTimeDiff.get(0),
    target: 'input'
  });

  new TimeDiffView({
    model: timeModel,
    el: $inputTimeDiff.get(0),
    target: 'input'
  });
  
  new TimeNowController({
    model: timeModel,
    el: '.now'
  });

  new OutputTimeView({
    model: timeModel,
    el: '.result'
  });

  new TimeDiffController({
    model: timeModel,
    el: $outputTimDiff.get(0),
    target: 'output'
  });

  new TimeDiffView({
    model: timeModel,
    el: $outputTimDiff.get(0),
    target: 'output'
  });
  
  new TimeFormatView({
    model: timeModel,
    el: $outputTimeFormat.get(0)
  });


  // 入力エリアにフォーカスを設定する
  // document.getElementById('convert-from').focus();
}
            
          
!
999px
Loading ..................

Console