Skip to content

Commit

Permalink
Properly handle timezones
Browse files Browse the repository at this point in the history
- Handle everything internally as UTC
- Display dates using the local timezone
  • Loading branch information
hulthe committed Jan 13, 2020
1 parent a66d609 commit 732d93c
Show file tree
Hide file tree
Showing 18 changed files with 425 additions and 466 deletions.
715 changes: 302 additions & 413 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dotenv = "0.13.0"
serde = "1"
serde_json = "1"
serde_derive = "1"
chrono = { version = "0.4", features = ["serde"] }
chrono = { version = "0.4.10", features = ["serde"] }
orion = "0.13.1"
hex = "0.3.2"
frank_jwt = "3.1.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
DROP VIEW events_with_signups;

ALTER TABLE transactions
ALTER COLUMN time TYPE timestamp without time zone;

ALTER TABLE events
ALTER COLUMN end_time TYPE timestamp without time zone,
ALTER COLUMN start_time TYPE timestamp without time zone;

CREATE OR REPLACE VIEW public.events_with_signups AS
SELECT
events.*,
COALESCE(t_signup_count.count, 0) AS signups
FROM
events
LEFT JOIN
(
SELECT
count(id),
event
FROM
event_signups
GROUP BY
event
) t_signup_count
ON events.id = t_signup_count.event;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
DROP VIEW events_with_signups;

ALTER TABLE transactions
ALTER COLUMN time TYPE timestamp with time zone;

ALTER TABLE events
ALTER COLUMN end_time TYPE timestamp with time zone,
ALTER COLUMN start_time TYPE timestamp with time zone;

CREATE OR REPLACE VIEW public.events_with_signups AS
SELECT
events.*,
COALESCE(t_signup_count.count, 0) AS signups
FROM
events
LEFT JOIN
(
SELECT
count(id),
event
FROM
event_signups
GROUP BY
event
) t_signup_count
ON events.id = t_signup_count.event;
14 changes: 7 additions & 7 deletions backend/src/models/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::schema::tables::events;
use crate::util::StatusJson;
use chrono::NaiveDateTime;
use chrono::{DateTime, Utc};
use juniper_codegen::GraphQLInputObject;
use rocket::http::Status;
use rocket::FromForm;
Expand Down Expand Up @@ -30,8 +30,8 @@ pub struct EventWithSignups {
pub title: String,
pub background: String,
pub location: String,
pub start_time: NaiveDateTime,
pub end_time: NaiveDateTime,
pub start_time: DateTime<Utc>,
pub end_time: DateTime<Utc>,
pub price: i32,
pub published: bool,
pub signups: i64,
Expand All @@ -43,8 +43,8 @@ pub struct Event {
pub title: String,
pub background: String,
pub location: String,
pub start_time: NaiveDateTime,
pub end_time: NaiveDateTime,
pub start_time: DateTime<Utc>,
pub end_time: DateTime<Utc>,
pub price: i32,
pub published: bool,
}
Expand All @@ -55,8 +55,8 @@ pub struct NewEvent {
pub title: String,
pub background: String,
pub location: String,
pub start_time: NaiveDateTime,
pub end_time: NaiveDateTime,
pub start_time: DateTime<Utc>,
pub end_time: DateTime<Utc>,
pub price: Option<i32>,
}

Expand Down
6 changes: 3 additions & 3 deletions backend/src/models/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ pub use laggit_api::transaction as object;
/// Relational data models - as represented by the database.
pub mod relational {
use crate::schema::tables::{transaction_bundles, transaction_items, transactions};
use chrono::NaiveDateTime;
use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};

#[derive(Insertable, Serialize, Deserialize, Debug, PartialEq)]
#[table_name = "transactions"]
pub struct NewTransaction {
pub description: Option<String>,
pub time: Option<NaiveDateTime>,
pub time: Option<DateTime<Utc>>,
pub debited_account: i32,
pub credited_account: i32,
pub amount: i32,
Expand All @@ -21,7 +21,7 @@ pub mod relational {
pub struct Transaction {
pub id: i32,
pub description: Option<String>,
pub time: NaiveDateTime,
pub time: DateTime<Utc>,
pub debited_account: i32,
pub credited_account: i32,
pub amount: i32,
Expand Down
23 changes: 14 additions & 9 deletions backend/src/models/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::schema::tables::users;
use chrono::{Duration, Utc};
use diesel::prelude::*;
use frank_jwt::error::Error as JWTError;
use frank_jwt::{decode, encode, Algorithm};
use frank_jwt::{decode, encode, Algorithm, ValidationOptions};
use orion::errors::UnknownCryptoError;
use orion::pwhash::{hash_password, Password};
use rocket::http::Status;
Expand Down Expand Up @@ -149,14 +149,19 @@ impl<'a, 'r> FromRequest<'a, 'r> for User {
.map(|header| header.trim_start_matches("Bearer "))
.next()
{
let jwt =
decode(&header.to_owned(), &jwt_config.secret, jwt_config.algorithm).map_err(|e| {
eprintln!("{}", e);
match e {
// TODO
_ => Outcome::Failure((Status::InternalServerError, ())),
}
});
let jwt = decode(
&header.to_owned(),
&jwt_config.secret,
jwt_config.algorithm,
&ValidationOptions::new(),
)
.map_err(|e| {
eprintln!("{}", e);
match e {
// TODO
_ => Outcome::Failure((Status::InternalServerError, ())),
}
});

let (_header, payload): (JsonValue, JsonValue) = match jwt {
Ok(jwt) => jwt,
Expand Down
6 changes: 3 additions & 3 deletions backend/src/routes/graphql/event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::context::Context;
use crate::models::event::EventWithSignups as Event;
use crate::models::signup::Signup;
use chrono::NaiveDateTime;
use chrono::{DateTime, Utc};
use diesel::prelude::*;
use juniper::{graphql_object, FieldResult};

Expand All @@ -17,9 +17,9 @@ graphql_object!(Event: Context |&self| {

field location() -> &str { self.location.as_str() }

field start_time() -> NaiveDateTime { self.start_time }
field start_time() -> DateTime<Utc> { self.start_time }

field end_time() -> NaiveDateTime { self.end_time }
field end_time() -> DateTime<Utc> { self.end_time }

field price() -> i32 { self.price }

Expand Down
6 changes: 3 additions & 3 deletions backend/src/routes/graphql/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ mod tests {
use crate::schema::tables::events;
use crate::util::catchers::catchers;
use crate::util::testing::{DatabaseState, UserSession};
use chrono::naive::NaiveDateTime;
use chrono::{DateTime, NaiveDateTime, Utc};
use diesel::RunQueryDsl;
use rocket::http::{ContentType, Header};
use rocket::local::Client;
Expand Down Expand Up @@ -181,8 +181,8 @@ mod tests {
title: "Test Event 2".into(),
background: "http://image.ru/png.jpg".into(),
location: "Fizzbuzz TX".into(),
start_time: NaiveDateTime::from_timestamp(10_000_000_00i64, 0),
end_time: NaiveDateTime::from_timestamp(10_000_001_00i64, 0),
start_time: DateTime::from_utc(NaiveDateTime::from_timestamp(10_000_000_00i64, 0), Utc),
end_time: DateTime::from_utc(NaiveDateTime::from_timestamp(10_000_001_00i64, 0), Utc),
price: None,
};
println!("Request Data: {:#?}\n", &new_event);
Expand Down
6 changes: 3 additions & 3 deletions backend/src/schema/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ table! {
title -> Text,
background -> Text,
location -> Text,
start_time -> Timestamp,
end_time -> Timestamp,
start_time -> Timestamptz,
end_time -> Timestamptz,
price -> Int4,
published -> Bool,
}
Expand Down Expand Up @@ -95,7 +95,7 @@ table! {
transactions (id) {
id -> Int4,
description -> Nullable<Text>,
time -> Timestamp,
time -> Timestamptz,
debited_account -> Int4,
credited_account -> Int4,
amount -> Int4,
Expand Down
4 changes: 2 additions & 2 deletions backend/src/schema/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ table! {
title -> Text,
background -> Text,
location -> Text,
start_time -> Timestamp,
end_time -> Timestamp,
start_time -> Timestamptz,
end_time -> Timestamptz,
price -> Int4,
published -> Bool,
signups -> Int8,
Expand Down
4 changes: 2 additions & 2 deletions backend/src/util/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::models::{NewEvent, NewSignup, User};
use crate::schema::tables::event_signups;
use crate::schema::tables::events;
use crate::schema::tables::users;
use chrono::{Duration, Local};
use chrono::{Duration, Utc};
use diesel::RunQueryDsl;
use dotenv::dotenv;

Expand All @@ -22,7 +22,7 @@ pub fn generate_new_events(old: usize, new: usize) -> Vec<NewEvent> {
}
};

let now = Local::now().naive_local();
let now = Utc::now();

for i in 0..old {
let time = now - Duration::weeks(2 * (i + 1) as i64);
Expand Down
4 changes: 2 additions & 2 deletions common/src/models/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::currency::Currency;
use crate::models::book_account::BookAccountId;
use crate::models::inventory::InventoryItemId;
use chrono::NaiveDateTime;
use chrono::{DateTime, Utc};
use std::collections::HashMap;

#[cfg(feature = "serde_impl")]
Expand All @@ -26,7 +26,7 @@ pub struct NewTransaction {
pub struct Transaction {
pub id: TransactionId,
pub description: Option<String>,
pub time: NaiveDateTime,
pub time: DateTime<Utc>,
pub bundles: Vec<TransactionBundle>,
pub debited_account: BookAccountId,
pub credited_account: BookAccountId,
Expand Down
6 changes: 5 additions & 1 deletion frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ crate-type = ["cdylib"]
# TODO: update this when new version is released
#seed = "=0.5.2"
seed = { git = "https://github.com/seed-rs/seed.git", branch = "master" }
chrono = { version = "0.4.6", features = ["serde"] }
cfg-if = "0.1.7"
wasm-bindgen = "^0.2.45"
strum = "0.15.0"
Expand All @@ -36,6 +35,11 @@ wee_alloc = { version = "0.4.3", optional = true }
# code size when deploying.
console_error_panic_hook = { version ="0.1.6", optional = true }

[dependencies.chrono]
version = "0.4.10"
default-features = false
features = ["serde", "wasmbind", "js-sys"]

[dependencies.laggit_api]
path="../common"

Expand Down
11 changes: 7 additions & 4 deletions frontend/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::page::{
transactions::{TransactionsMsg, TransactionsPage},
Page,
};
use chrono::NaiveDateTime;
use laggit_api::{
book_account::{BookAccount, BookAccountId, MasterAccounts},
inventory::{
Expand All @@ -24,6 +23,7 @@ use std::collections::HashMap;
use std::fmt::Debug;
use std::rc::Rc;
use web_sys;
use chrono::{DateTime, Utc, Local, FixedOffset};

#[derive(Clone, Default)]
pub struct StateLoading {
Expand All @@ -32,13 +32,13 @@ pub struct StateLoading {
pub transaction_history: Option<Vec<Transaction>>,
pub inventory: Option<HashMap<InventoryItemId, Rc<InventoryItem>>>,
pub bundles: Option<HashMap<InventoryBundleId, Rc<InventoryBundle>>>,
pub events: Option<BTreeMap<NaiveDateTime, Vec<Event>>>,
pub events: Option<BTreeMap<DateTime<Utc>, Vec<Event>>>,
pub members: Option<HashMap<MemberId, Rc<Member>>>,
}

#[derive(Clone)]
pub struct StateReady {
pub events: BTreeMap<NaiveDateTime, Vec<Event>>,
pub events: BTreeMap<DateTime<Utc>, Vec<Event>>,

pub book_accounts: HashMap<BookAccountId, Rc<BookAccount>>,
pub master_accounts: MasterAccounts,
Expand All @@ -49,6 +49,8 @@ pub struct StateReady {

pub inventory: HashMap<InventoryItemId, Rc<InventoryItem>>,
pub bundles: HashMap<InventoryBundleId, Rc<InventoryBundle>>,

pub timezone: FixedOffset,
}

#[derive(Clone)]
Expand Down Expand Up @@ -172,6 +174,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
bundles: bundles.clone(),
events: events.clone(),
members: members.clone(),
timezone: *Local::now().offset(),
};
State::Ready {
accounting_page: AccountingPage::new(&data),
Expand Down Expand Up @@ -204,7 +207,7 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
use FetchMsg::*;
match msg {
Events(fetch) => handle_fetch(model, fetch, "event", |data, s| {
let mut events: BTreeMap<NaiveDateTime, Vec<Event>> = BTreeMap::new();
let mut events: BTreeMap<DateTime<Utc>, Vec<Event>> = BTreeMap::new();
for event in data {
events.entry(event.start_time).or_default().push(event)
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/models/event.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use chrono::NaiveDateTime;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -7,8 +7,8 @@ pub struct Event {
pub title: String,
pub background: String,
pub location: String,
pub start_time: NaiveDateTime,
pub end_time: NaiveDateTime,
pub start_time: DateTime<Utc>,
pub end_time: DateTime<Utc>,
pub price: i32,
pub published: bool,
pub signups: i64,
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/page/accounting.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::app::{Msg, StateReady};
//use crate::generated::css_classes::C;
use chrono::{NaiveDate, NaiveTime};
use chrono::{DateTime, NaiveDate, NaiveTime, Utc};
use laggit_api::{book_account::BookAccountId, currency::Currency};
use seed::{prelude::*, *};
use std::collections::HashMap;
Expand Down Expand Up @@ -125,8 +125,8 @@ impl AccountingPage {
.transaction_history
.iter()
.filter(|tr| match (end_date, end_time) {
(Some(ed), Some(et)) => tr.time <= ed.and_time(et),
(Some(ed), None) => tr.time <= ed.and_hms(23, 59, 59),
(Some(ed), Some(et)) => tr.time <= DateTime::from_utc(ed.and_time(et), Utc),
(Some(ed), None) => tr.time <= DateTime::from_utc(ed.and_hms(23, 59, 59), Utc),
(None, _) => true,
})
{
Expand Down
Loading

0 comments on commit 732d93c

Please sign in to comment.