Skip to content

Instantly share code, notes, and snippets.

@ninjapanzer
Last active April 26, 2016 21:22
Show Gist options
  • Select an option

  • Save ninjapanzer/79c7b9322def97b90b54 to your computer and use it in GitHub Desktop.

Select an option

Save ninjapanzer/79c7b9322def97b90b54 to your computer and use it in GitHub Desktop.
Timezone_Rails
//eonasdan-bootstrap-datetimepicker
jQuery('#datetimepickerStart').datetimepicker({
sideBySide: true
});
jQuery('#datetimepickerStop').datetimepicker({
sideBySide: true,
useCurrent: false //Important! See issue #1075
});
jQuery('#datetimepickerStart').on('dp.change', function (e) {
jQuery('#datetimepickerStop').data('DateTimePicker').minDate(e.date);
});
jQuery('#datetimepickerStop').on('dp.change', function (e) {
jQuery('#datetimepickerStart').data('DateTimePicker').maxDate(e.date);
});
// Timezone
var zoneOffset = moment().format('Z')
jQuery('.detectedTimezone').html(jstz.determine().name())
if(jQuery("#eventTimezone select").val() === ""){
jQuery("#eventTimezone select").val(zoneOffset);
}
jQuery('.detectedOffset').html(zoneOffset);
class Event < ActiveRecord::Base
PARSE_DATE_FORMAT = '%m/%d/%Y %l:%M %p %:z'
DISPLAY_DATE_FORMAT = '%m/%d/%Y %l:%M %p'
TIMEZONES = [
HAWAII = { hawaii: '-10:00'},
ALASKA = { alaska: '-09:00'},
PACIFIC = { pacific: '-08:00'},
MOUNTAIN = { mountain: '-07:00'},
CENTRAL = { central: '-06:00'},
EASTERN = { eastern: '-05:00'},
ATLANTIC = { atlantic: '-04:00'}
].reduce( {}, :merge )
scope :future, ->{ where("event_start >= :date", date: Time.now) }
scope :current, ->{ where("event_start <= ? AND event_end >= ?", Time.now, Time.now) }
scope :past, ->{ where("event_end < :date", date: Time.now) }
def self.display_timezones
TIMEZONES.map{ |zone, offset| ["#{zone.capitalize} \t #{offset}", offset] }
end
def format_start
return "" unless event_start
apply_time_zone(event_start).strftime(Event::DISPLAY_DATE_FORMAT)
end
def format_end
return "" unless event_end
apply_time_zone(event_end).strftime(Event::DISPLAY_DATE_FORMAT)
end
def start_date_ratio_to_end_of_year
days = days_to_event
days_in_year = ((DateTime.now.end_of_year - DateTime.now.beginning_of_year).to_i + 1).to_f
((days/days_in_year)*100).ceil
end
def days_to_event
event_beginning_on = event_start.to_date
current_time = Date.today
days = (event_beginning_on - current_time).to_i
return 0 if days < 0
days
end
private
def apply_time_zone(datetime)
tz_offset = time_zone.split(':')[0].to_i
tz = ActiveSupport::TimeZone[tz_offset]
datetime.in_time_zone(tz)
end
end
class EventsController < ApplicationController
before_action :event_from_params, only: [:show, :edit, :update]
def index
@events = Event.all
end
def show
@event = Event.find(params[:id])
end
def new
@event = Event.new
end
def create
@event = Event.new
@event.assign_attributes transform_param_dates
if @event.valid?
@event.save
redirect_to edit_event_path(@event)
else
render 'edit'
end
end
def edit; end
def update
@event.assign_attributes transform_param_dates
if @event.valid?
@event.save
redirect_to edit_event_path(@event)
else
render 'edit'
end
end
def future
@events = Event.future
render json: {events: @events}
end
def past
@events = Event.past
render json: {events: @events}
end
private
def parse_event_date_params
date_keys = ['event_start', 'event_end']
time_zone = event_params['time_zone']
event_params
.select{ |key| date_keys.include?(key) }
.map{ |key, value| {key => interpret_date(value, time_zone)} }
.reduce(:merge)
end
def interpret_date(str, tz)
date_time = DateTime.strptime("#{str} #{tz}", Event::PARSE_DATE_FORMAT)
date_time.to_time.utc
end
def event_from_params
@event = Event.find(params['id'])
end
def transform_param_dates
event_params.merge parse_event_date_params
end
def event_params
params.require(:event).permit(:client_id, :event_type, :event_start, :event_end, :time_zone)
end
end
= form_for @event do |f|
- if @event.errors.any?
#error_explanation
%h2= "#{pluralize(@event.errors.count, 'error')} prohibited this contact from being saved:"
%ul
- @event.errors.full_messages.each do |msg|
%li= msg
.form-group
.col-md-10.field
= f.label :event_type, 'Type'
= f.select(:event_type, Event::TYPES.collect { |p| p }, {prompt: 'Select One'})
.form-group
.col-md-10
%label Event Dates:
.col-md-5
%label Begins:
#datetimepickerStart.input-group.date
= f.text_field :event_start, {class: 'form-control', value: @event.format_start}
.input-group-addon
%span.glyphicon.glyphicon-calendar
.col-md-5
%label Ends:
#datetimepickerStop.input-group.date
= f.text_field :event_end, {class: 'form-control', value: @event.format_end}
.input-group-addon
%span.glyphicon.glyphicon-calendar
.col-md-10
%label Timezone (UTC Offset):
#eventTimezone.input-group.timezone
= f.select(:time_zone, Event.display_timezones, {prompt: 'Select One'})
%span Detected:
%span.detectedTimezone
%span.detectedOffset
.form-group
.col-md-10
%label.col-sm-2.control-label Client
.col-sm-10
= f.collection_select :client_id, Client.order(:name),:id,:name, {prompt: '- Select One -'}
.form-group
.col-md-10.actions
= f.submit 'Save', {:class=>"btn btn-default"}
= link_to "Cancel", :back, {:class=>"btn btn-default"}
@ninjapanzer
Copy link
Author

The JS also requires moment with locales to handle some of the timezone detection

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment