diff --git a/Cargo.lock b/Cargo.lock
index 282e50f44..434c4c7b5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -564,7 +564,6 @@ dependencies = [
  "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -598,6 +597,7 @@ version = "0.3.0"
 dependencies = [
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "croaring 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -613,7 +613,6 @@ dependencies = [
  "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -637,6 +636,7 @@ dependencies = [
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "croaring 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -650,7 +650,6 @@ dependencies = [
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -674,6 +673,7 @@ version = "0.3.0"
 dependencies = [
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "grin_core 0.3.0",
  "grin_pool 0.3.0",
@@ -686,7 +686,6 @@ dependencies = [
  "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -694,6 +693,7 @@ name = "grin_pool"
 version = "0.3.0"
 dependencies = [
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "grin_chain 0.3.0",
  "grin_core 0.3.0",
  "grin_keychain 0.3.0",
@@ -704,7 +704,6 @@ dependencies = [
  "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -713,6 +712,7 @@ version = "0.3.0"
 dependencies = [
  "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "grin_api 0.3.0",
  "grin_chain 0.3.0",
  "grin_config 0.3.0",
@@ -733,7 +733,6 @@ dependencies = [
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -741,6 +740,7 @@ name = "grin_store"
 version = "0.3.0"
 dependencies = [
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "croaring 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -754,7 +754,6 @@ dependencies = [
  "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -802,7 +801,6 @@ dependencies = [
  "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "urlencoded 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 9a75329e7..9328b0735 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@ path = "src/bin/grin.rs"
 
 [dependencies]
 blake2-rfc = "0.2"
-chrono = "0.4"
+chrono = "0.4.4"
 clap = "2.31"
 ctrlc = { version = "3.1", features = ["termination"] }
 daemonize = "0.3"
@@ -24,7 +24,6 @@ serde = "1"
 serde_json = "1"
 slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_trace"] }
 term = "0.5"
-time = "0.1"
 
 grin_api = { path = "./api" }
 grin_config = { path = "./config" }
diff --git a/api/src/types.rs b/api/src/types.rs
index 9d08f9407..dcd768c8d 100644
--- a/api/src/types.rs
+++ b/api/src/types.rs
@@ -498,7 +498,7 @@ impl BlockHeaderPrintable {
 			version: h.version,
 			height: h.height,
 			previous: util::to_hex(h.previous.to_vec()),
-			timestamp: h.timestamp.rfc3339().to_string(),
+			timestamp: h.timestamp.to_rfc3339(),
 			output_root: util::to_hex(h.output_root.to_vec()),
 			range_proof_root: util::to_hex(h.range_proof_root.to_vec()),
 			kernel_root: util::to_hex(h.kernel_root.to_vec()),
diff --git a/chain/Cargo.toml b/chain/Cargo.toml
index b54ca1ada..774f0d45e 100644
--- a/chain/Cargo.toml
+++ b/chain/Cargo.toml
@@ -15,7 +15,7 @@ croaring = "=0.3.2"
 slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_trace"] }
 serde = "1"
 serde_derive = "1"
-time = "0.1"
+chrono = "0.4.4"
 lru-cache = "0.1"
 
 grin_core = { path = "../core" }
diff --git a/chain/src/lib.rs b/chain/src/lib.rs
index 6d8fedbe2..15c2a51ad 100644
--- a/chain/src/lib.rs
+++ b/chain/src/lib.rs
@@ -32,7 +32,7 @@ extern crate serde_derive;
 #[macro_use]
 extern crate slog;
 extern crate failure;
-extern crate time;
+extern crate chrono;
 #[macro_use]
 extern crate failure_derive;
 
diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs
index 221d22abc..66eb904b8 100644
--- a/chain/src/pipe.rs
+++ b/chain/src/pipe.rs
@@ -17,7 +17,8 @@
 use std::collections::VecDeque;
 use std::sync::{Arc, RwLock};
 
-use time;
+use chrono::prelude::{Utc};
+use chrono::Duration;
 
 use core::consensus;
 use core::core::hash::{Hash, Hashed};
@@ -218,7 +219,7 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
 
 	// TODO: remove CI check from here somehow
 	if header.timestamp
-		> time::now_utc() + time::Duration::seconds(12 * (consensus::BLOCK_TIME_SEC as i64))
+		> Utc::now() + Duration::seconds(12 * (consensus::BLOCK_TIME_SEC as i64))
 		&& !global::is_automated_testing_mode()
 	{
 		// refuse blocks more than 12 blocks intervals in future (as in bitcoin)
diff --git a/chain/src/store.rs b/chain/src/store.rs
index 52f9761ef..e399fc59b 100644
--- a/chain/src/store.rs
+++ b/chain/src/store.rs
@@ -447,7 +447,7 @@ impl Iterator for DifficultyIter {
 				.map_or(Difficulty::zero(), |x| x.total_difficulty);
 			let difficulty = header.total_difficulty - prev_difficulty;
 
-			Some(Ok((header.timestamp.to_timespec().sec as u64, difficulty)))
+			Some(Ok((header.timestamp.timestamp() as u64, difficulty)))
 		} else {
 			return None;
 		}
diff --git a/chain/tests/data_file_integrity.rs b/chain/tests/data_file_integrity.rs
index 67b80228d..972514fa3 100644
--- a/chain/tests/data_file_integrity.rs
+++ b/chain/tests/data_file_integrity.rs
@@ -20,10 +20,11 @@ extern crate grin_store as store;
 extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::sync::Arc;
+use chrono::Duration;
 
 use chain::Chain;
 use chain::types::{NoopAdapter, Tip};
@@ -79,7 +80,7 @@ fn data_files() {
 			let pk = keychain.derive_key_id(n as u32).unwrap();
 			let reward = libtx::reward::output(&keychain, &pk, 0, prev.height).unwrap();
 			let mut b = core::core::Block::new(&prev, vec![], difficulty.clone(), reward).unwrap();
-			b.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+			b.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 			chain.set_txhashset_roots(&mut b, false).unwrap();
 
@@ -162,7 +163,7 @@ fn _prepare_block_nosum(
 		Err(e) => panic!("{:?}", e),
 		Ok(b) => b,
 	};
-	b.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	b.header.timestamp = prev.timestamp + Duration::seconds(60);
 	b.header.total_difficulty = Difficulty::from_num(diff);
 	b
 }
diff --git a/chain/tests/mine_simple_chain.rs b/chain/tests/mine_simple_chain.rs
index 3ff194322..0bd4a84df 100644
--- a/chain/tests/mine_simple_chain.rs
+++ b/chain/tests/mine_simple_chain.rs
@@ -19,10 +19,11 @@ extern crate grin_store as store;
 extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::sync::Arc;
+use chrono::Duration;
 
 use chain::Chain;
 use chain::types::NoopAdapter;
@@ -63,7 +64,7 @@ fn mine_empty_chain() {
 		let pk = keychain.derive_key_id(n as u32).unwrap();
 		let reward = libtx::reward::output(&keychain, &pk, 0, prev.height).unwrap();
 		let mut b = core::core::Block::new(&prev, vec![], difficulty.clone(), reward).unwrap();
-		b.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+		b.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 		chain.set_txhashset_roots(&mut b, false).unwrap();
 
@@ -435,7 +436,7 @@ where
 		Err(e) => panic!("{:?}", e),
 		Ok(b) => b,
 	};
-	b.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	b.header.timestamp = prev.timestamp + Duration::seconds(60);
 	b.header.total_difficulty = prev.total_difficulty.clone() + Difficulty::from_num(diff);
 	b.header.pow = core::core::Proof::random(proof_size);
 	b
diff --git a/chain/tests/test_coinbase_maturity.rs b/chain/tests/test_coinbase_maturity.rs
index 130ffee40..e82ec5bea 100644
--- a/chain/tests/test_coinbase_maturity.rs
+++ b/chain/tests/test_coinbase_maturity.rs
@@ -19,10 +19,11 @@ extern crate grin_keychain as keychain;
 extern crate grin_store as store;
 extern crate grin_wallet as wallet;
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::sync::Arc;
+use chrono::Duration;
 
 use chain::types::NoopAdapter;
 use chain::{Error, ErrorKind};
@@ -64,7 +65,7 @@ fn test_coinbase_maturity() {
 
 	let reward = libtx::reward::output(&keychain, &key_id1, 0, prev.height).unwrap();
 	let mut block = core::core::Block::new(&prev, vec![], Difficulty::one(), reward).unwrap();
-	block.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	block.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 	let difficulty = consensus::next_difficulty(chain.difficulty_iter()).unwrap();
 
@@ -118,7 +119,7 @@ fn test_coinbase_maturity() {
 	let fees = txs.iter().map(|tx| tx.fee()).sum();
 	let reward = libtx::reward::output(&keychain, &key_id3, fees, prev.height).unwrap();
 	let mut block = core::core::Block::new(&prev, txs, Difficulty::one(), reward).unwrap();
-	block.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	block.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 	let difficulty = consensus::next_difficulty(chain.difficulty_iter()).unwrap();
 
@@ -151,7 +152,7 @@ fn test_coinbase_maturity() {
 
 		let reward = libtx::reward::output(&keychain, &pk, 0, prev.height).unwrap();
 		let mut block = core::core::Block::new(&prev, vec![], Difficulty::one(), reward).unwrap();
-		block.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+		block.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 		let difficulty = consensus::next_difficulty(chain.difficulty_iter()).unwrap();
 
@@ -178,7 +179,7 @@ fn test_coinbase_maturity() {
 	let reward = libtx::reward::output(&keychain, &key_id4, fees, prev.height).unwrap();
 	let mut block = core::core::Block::new(&prev, txs, Difficulty::one(), reward).unwrap();
 
-	block.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	block.header.timestamp = prev.timestamp + Duration::seconds(60);
 
 	let difficulty = consensus::next_difficulty(chain.difficulty_iter()).unwrap();
 
diff --git a/core/Cargo.toml b/core/Cargo.toml
index affbfc2e6..4b9fc53b3 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -19,7 +19,7 @@ serde = "1"
 serde_derive = "1"
 siphasher = "0.2"
 slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_trace"] }
-time = "0.1"
+chrono = "0.4.4"
 
 grin_keychain = { path = "../keychain" }
 grin_util = { path = "../util" }
diff --git a/core/src/core/block.rs b/core/src/core/block.rs
index 300a789a2..18a127d7a 100644
--- a/core/src/core/block.rs
+++ b/core/src/core/block.rs
@@ -18,7 +18,7 @@ use rand::{thread_rng, Rng};
 use std::collections::HashSet;
 use std::fmt;
 use std::iter::FromIterator;
-use time;
+use chrono::prelude::{DateTime, NaiveDateTime, Utc};
 
 use consensus::{self, exceeds_weight, reward, VerifySortOrder, REWARD};
 use core::committed::{self, Committed};
@@ -114,7 +114,7 @@ pub struct BlockHeader {
 	/// Hash of the block previous to this in the chain.
 	pub previous: Hash,
 	/// Timestamp at which the block was built.
-	pub timestamp: time::Tm,
+	pub timestamp: DateTime<Utc>,
 	/// Total accumulated difficulty since genesis block
 	pub total_difficulty: Difficulty,
 	/// Merklish root of all the commitments in the TxHashSet
@@ -147,7 +147,7 @@ impl Default for BlockHeader {
 			version: 1,
 			height: 0,
 			previous: ZERO_HASH,
-			timestamp: time::at_utc(time::Timespec { sec: 0, nsec: 0 }),
+			timestamp: DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
 			total_difficulty: Difficulty::one(),
 			output_root: ZERO_HASH,
 			range_proof_root: ZERO_HASH,
@@ -198,10 +198,7 @@ impl Readable for BlockHeader {
 			version,
 			height,
 			previous,
-			timestamp: time::at_utc(time::Timespec {
-				sec: timestamp,
-				nsec: 0,
-			}),
+			timestamp: DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(timestamp, 0), Utc),
 			total_difficulty,
 			output_root,
 			range_proof_root,
@@ -224,7 +221,7 @@ impl BlockHeader {
 			[write_u16, self.version],
 			[write_u64, self.height],
 			[write_fixed_bytes, &self.previous],
-			[write_i64, self.timestamp.to_timespec().sec],
+			[write_i64, self.timestamp.timestamp()],
 			[write_u64, self.total_difficulty.to_num()],
 			[write_fixed_bytes, &self.output_root],
 			[write_fixed_bytes, &self.range_proof_root],
@@ -612,10 +609,7 @@ impl Block {
 		Ok(Block {
 			header: BlockHeader {
 				height: prev.height + 1,
-				timestamp: time::Tm {
-					tm_nsec: 0,
-					..time::now_utc()
-				},
+				timestamp: Utc::now(),
 				previous: prev.hash(),
 				total_difficulty: difficulty + prev.total_difficulty,
 				total_kernel_offset,
diff --git a/core/src/genesis.rs b/core/src/genesis.rs
index 6bf4ca4d8..d6da60257 100644
--- a/core/src/genesis.rs
+++ b/core/src/genesis.rs
@@ -14,7 +14,7 @@
 
 //! Definition of the genesis block. Placeholder for now.
 
-use time;
+use chrono::prelude::{Utc, TimeZone};
 
 use consensus;
 use core;
@@ -29,12 +29,7 @@ pub fn genesis_dev() -> core::Block {
 		header: core::BlockHeader {
 			height: 0,
 			previous: core::hash::Hash([0xff; 32]),
-			timestamp: time::Tm {
-				tm_year: 1997 - 1900,
-				tm_mon: 7,
-				tm_mday: 4,
-				..time::empty_tm()
-			},
+			timestamp: Utc.ymd(1997, 7, 4).and_hms(0, 0, 0),
 			nonce: global::get_genesis_nonce(),
 			..Default::default()
 		},
@@ -51,13 +46,7 @@ pub fn genesis_testnet1() -> core::Block {
 		header: core::BlockHeader {
 			height: 0,
 			previous: core::hash::Hash([0xff; 32]),
-			timestamp: time::Tm {
-				tm_year: 2017 - 1900,
-				tm_mon: 10,
-				tm_mday: 16,
-				tm_hour: 20,
-				..time::empty_tm()
-			},
+			timestamp: Utc.ymd(2017, 10, 16).and_hms(20, 0, 0),
 			nonce: 28205,
 			pow: core::Proof::new(vec![
 				0x21e, 0x7a2, 0xeae, 0x144e, 0x1b1c, 0x1fbd, 0x203a, 0x214b, 0x293b, 0x2b74,
@@ -80,13 +69,7 @@ pub fn genesis_testnet2() -> core::Block {
 		header: core::BlockHeader {
 			height: 0,
 			previous: core::hash::Hash([0xff; 32]),
-			timestamp: time::Tm {
-				tm_year: 2018 - 1900,
-				tm_mon: 2,
-				tm_mday: 26,
-				tm_hour: 16,
-				..time::empty_tm()
-			},
+			timestamp: Utc.ymd(2018, 2, 26).and_hms(16, 0, 0),
 			total_difficulty: Difficulty::from_num(global::initial_block_difficulty()),
 			nonce: 1060,
 			pow: core::Proof::new(vec![
@@ -111,13 +94,7 @@ pub fn genesis_testnet3() -> core::Block {
 		header: core::BlockHeader {
 			height: 0,
 			previous: core::hash::Hash([0xff; 32]),
-			timestamp: time::Tm {
-				tm_year: 2018 - 1900,
-				tm_mon: 6,
-				tm_mday: 8,
-				tm_hour: 18,
-				..time::empty_tm()
-			},
+			timestamp: Utc.ymd(2018, 6, 8).and_hms(18, 0, 0),
 			total_difficulty: Difficulty::from_num(global::initial_block_difficulty()),
 			nonce: 4956988373127691,
 			pow: core::Proof::new(vec![
@@ -144,12 +121,7 @@ pub fn genesis_main() -> core::Block {
 		header: core::BlockHeader {
 			height: 0,
 			previous: core::hash::Hash([0xff; 32]),
-			timestamp: time::Tm {
-				tm_year: 2018 - 1900,
-				tm_mon: 7,
-				tm_mday: 14,
-				..time::empty_tm()
-			},
+			timestamp: Utc.ymd(2018, 7, 14).and_hms(0, 0, 0),
 			total_difficulty: Difficulty::from_num(global::initial_block_difficulty()),
 			nonce: global::get_genesis_nonce(),
 			pow: core::Proof::zero(consensus::PROOFSIZE),
diff --git a/core/src/lib.rs b/core/src/lib.rs
index 515c92d8b..a51968898 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -39,7 +39,7 @@ extern crate siphasher;
 #[macro_use]
 extern crate slog;
 extern crate failure;
-extern crate time;
+extern crate chrono;
 #[macro_use]
 extern crate failure_derive;
 
diff --git a/core/src/pow/mod.rs b/core/src/pow/mod.rs
index 809d6894d..b860e9058 100644
--- a/core/src/pow/mod.rs
+++ b/core/src/pow/mod.rs
@@ -31,13 +31,14 @@
 extern crate blake2_rfc as blake2;
 extern crate rand;
 extern crate serde;
-extern crate time;
+extern crate chrono;
 
 extern crate grin_util as util;
 
 pub mod cuckoo;
 mod siphash;
 
+use chrono::prelude::{DateTime, NaiveDateTime, Utc};
 use consensus;
 use core::target::Difficulty;
 use core::{Block, BlockHeader};
@@ -57,7 +58,7 @@ pub fn mine_genesis_block() -> Result<Block, Error> {
 	let mut gen = genesis::genesis_testnet2();
 	if global::is_user_testing_mode() || global::is_automated_testing_mode() {
 		gen = genesis::genesis_dev();
-		gen.header.timestamp = time::now();
+		gen.header.timestamp = Utc::now();
 	}
 
 	// total_difficulty on the genesis header *is* the difficulty of that block
@@ -104,7 +105,7 @@ pub fn pow_size(
 		// and if we're back where we started, update the time (changes the hash as
 		// well)
 		if bh.nonce == start_nonce {
-			bh.timestamp = time::at_utc(time::Timespec { sec: 0, nsec: 0 });
+			bh.timestamp = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc);
 		}
 	}
 }
diff --git a/core/tests/block.rs b/core/tests/block.rs
index 3a5bf3710..0388467f5 100644
--- a/core/tests/block.rs
+++ b/core/tests/block.rs
@@ -16,6 +16,7 @@ extern crate grin_core;
 extern crate grin_keychain as keychain;
 extern crate grin_util as util;
 extern crate grin_wallet as wallet;
+extern crate chrono;
 
 pub mod common;
 
@@ -29,6 +30,7 @@ use grin_core::core::{Block, BlockHeader, CompactBlock, KernelFeatures, OutputFe
 use grin_core::{global, ser};
 use keychain::{BlindingFactor, ExtKeychain, Keychain};
 use std::time::Instant;
+use chrono::Duration;
 use util::{secp, secp_static};
 use wallet::libtx::build::{self, input, output, with_fee};
 
@@ -213,12 +215,17 @@ fn serialize_deserialize_block() {
 	let keychain = ExtKeychain::from_random_seed().unwrap();
 	let prev = BlockHeader::default();
 	let key_id = keychain.derive_key_id(1).unwrap();
-	let b = new_block(vec![], &keychain, &prev, &key_id);
+	let mut b = new_block(vec![], &keychain, &prev, &key_id);
 
 	let mut vec = Vec::new();
 	ser::serialize(&mut vec, &b).expect("serialization failed");
 	let b2: Block = ser::deserialize(&mut &vec[..]).unwrap();
 
+	// After header serialization, timestamp will lose 'nanos' info, that's the designed behavior.
+	// To suppress 'nanos' difference caused assertion fail, we force b.header also lose 'nanos'.
+	let origin_ts = b.header.timestamp;
+	b.header.timestamp = origin_ts - Duration::nanoseconds(origin_ts.timestamp_subsec_nanos() as i64);
+
 	assert_eq!(b.header, b2.header);
 	assert_eq!(b.inputs, b2.inputs);
 	assert_eq!(b.outputs, b2.outputs);
diff --git a/core/tests/consensus.rs b/core/tests/consensus.rs
index 26b757755..f34d2799b 100644
--- a/core/tests/consensus.rs
+++ b/core/tests/consensus.rs
@@ -14,13 +14,14 @@
 //! core consensus.rs tests (separated to de-clutter consensus.rs)
 #[macro_use]
 extern crate grin_core as core;
-extern crate time;
+extern crate chrono;
 
 use core::consensus::{next_difficulty, valid_header_version, TargetError,
                       DIFFICULTY_ADJUST_WINDOW, MEDIAN_TIME_WINDOW,
                       UPPER_TIME_BOUND, BLOCK_TIME_WINDOW, DAMP_FACTOR, MEDIAN_TIME_INDEX};
 use core::core::target::Difficulty;
 use std::fmt::{self, Display};
+use chrono::prelude::{Utc};
 use core::global;
 
 /// Last n blocks for difficulty calculation purposes
@@ -84,7 +85,7 @@ fn repeat(
 ) -> Vec<Result<(u64, Difficulty), TargetError>> {
 	let cur_time = match cur_time {
 		Some(t) => t,
-		None => time::get_time().sec as u64,
+		None => Utc::now().timestamp() as u64,
 	};
 	// watch overflow here, length shouldn't be ridiculous anyhow
 	assert!(len < std::usize::MAX as u64);
@@ -101,15 +102,15 @@ fn create_chain_sim(diff: u64)
 	-> Vec<((Result<(u64, Difficulty), TargetError>), DiffStats)> {
 	println!(
 		"adding create: {}, {}",
-		time::get_time().sec,
+		Utc::now().timestamp(),
 		Difficulty::from_num(diff)
 	);
 	let return_vec = vec![
-		Ok((time::get_time().sec as u64, Difficulty::from_num(diff))),
+		Ok((Utc::now().timestamp() as u64, Difficulty::from_num(diff))),
 	];
 	let diff_stats = get_diff_stats(&return_vec);
 	vec![
-		(Ok((time::get_time().sec as u64, Difficulty::from_num(diff))), diff_stats),
+		(Ok((Utc::now().timestamp() as u64, Difficulty::from_num(diff))), diff_stats),
 	]
 }
 
@@ -413,7 +414,7 @@ fn adjustment_scenarios() {
 #[test]
 fn next_target_adjustment() {
 	global::set_mining_mode(global::ChainTypes::AutomatedTesting);
-	let cur_time = time::get_time().sec as u64;
+	let cur_time = Utc::now().timestamp() as u64;
 
 	assert_eq!(
 		next_difficulty(vec![Ok((cur_time, Difficulty::one()))]).unwrap(),
diff --git a/p2p/Cargo.toml b/p2p/Cargo.toml
index 870d56c25..d35aa3b37 100644
--- a/p2p/Cargo.toml
+++ b/p2p/Cargo.toml
@@ -16,7 +16,7 @@ rand = "0.3"
 serde = "1"
 serde_derive = "1"
 slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_trace"] }
-time = "0.1"
+chrono = "0.4.4"
 
 grin_core = { path = "../core" }
 grin_store = { path = "../store" }
diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs
index 197f02ece..ce3bcc21b 100644
--- a/p2p/src/lib.rs
+++ b/p2p/src/lib.rs
@@ -38,7 +38,7 @@ extern crate serde;
 extern crate serde_derive;
 #[macro_use]
 extern crate slog;
-extern crate time;
+extern crate chrono;
 
 mod conn;
 pub mod handshake;
diff --git a/p2p/src/peers.rs b/p2p/src/peers.rs
index f8d63ddc6..60966e1ac 100644
--- a/p2p/src/peers.rs
+++ b/p2p/src/peers.rs
@@ -22,7 +22,7 @@ use rand::{thread_rng, Rng};
 use core::core;
 use core::core::hash::{Hash, Hashed};
 use core::core::target::Difficulty;
-use time;
+use chrono::prelude::{Utc};
 use util::LOGGER;
 
 use peer::Peer;
@@ -87,7 +87,7 @@ impl Peers {
 				dandelion_relay
 					.write()
 					.unwrap()
-					.insert(time::now_utc().to_timespec().sec, peer.clone());
+					.insert(Utc::now().timestamp(), peer.clone());
 				debug!(
 					LOGGER,
 					"Successfully updated Dandelion relay to: {}",
@@ -262,7 +262,7 @@ impl Peers {
 		}
 
 		if let Err(e) =
-			self.update_last_banned(peer_addr.clone(), time::now_utc().to_timespec().sec)
+			self.update_last_banned(peer_addr.clone(), Utc::now().timestamp())
 		{
 			error!(
 				LOGGER,
diff --git a/pool/Cargo.toml b/pool/Cargo.toml
index df227f955..e91cdc33a 100644
--- a/pool/Cargo.toml
+++ b/pool/Cargo.toml
@@ -11,7 +11,7 @@ rand = "0.3"
 serde = "1"
 serde_derive = "1"
 slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_trace"] }
-time = "0.1"
+chrono = "0.4.4"
 
 grin_core = { path = "../core" }
 grin_keychain = { path = "../keychain" }
diff --git a/pool/src/lib.rs b/pool/src/lib.rs
index 249f9ead3..d7cf1d5c4 100644
--- a/pool/src/lib.rs
+++ b/pool/src/lib.rs
@@ -31,7 +31,7 @@ extern crate serde;
 extern crate serde_derive;
 #[macro_use]
 extern crate slog;
-extern crate time;
+extern crate chrono;
 
 mod pool;
 pub mod transaction_pool;
diff --git a/pool/src/transaction_pool.rs b/pool/src/transaction_pool.rs
index 55fb25af7..68f1723cb 100644
--- a/pool/src/transaction_pool.rs
+++ b/pool/src/transaction_pool.rs
@@ -18,7 +18,7 @@
 //! valid chain state.
 
 use std::sync::Arc;
-use time;
+use chrono::prelude::{Utc};
 
 use core::core::hash::Hashed;
 use core::core::{transaction, Block, CompactBlock, Transaction};
@@ -119,7 +119,7 @@ where
 		let entry = PoolEntry {
 			state: PoolEntryState::Fresh,
 			src,
-			tx_at: time::now_utc().to_timespec(),
+			tx_at: Utc::now(),
 			tx: tx.clone(),
 		};
 
diff --git a/pool/src/types.rs b/pool/src/types.rs
index b33333cd6..5e7122a5d 100644
--- a/pool/src/types.rs
+++ b/pool/src/types.rs
@@ -16,7 +16,7 @@
 //! and its top-level members.
 
 use std::{error, fmt};
-use time::Timespec;
+use chrono::prelude::{DateTime, Utc};
 
 use core::consensus;
 use core::core::transaction::{self, Transaction};
@@ -119,7 +119,7 @@ pub struct PoolEntry {
 	/// Info on where this tx originated from.
 	pub src: TxSource,
 	/// Timestamp of when this tx was originally added to the pool.
-	pub tx_at: Timespec,
+	pub tx_at: DateTime<Utc>,
 	/// The transaction itself.
 	pub tx: Transaction,
 }
diff --git a/pool/tests/block_building.rs b/pool/tests/block_building.rs
index c649b8025..4f73d474f 100644
--- a/pool/tests/block_building.rs
+++ b/pool/tests/block_building.rs
@@ -21,7 +21,7 @@ extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 pub mod common;
 
diff --git a/pool/tests/block_reconciliation.rs b/pool/tests/block_reconciliation.rs
index 9e95b5857..7fe4cca69 100644
--- a/pool/tests/block_reconciliation.rs
+++ b/pool/tests/block_reconciliation.rs
@@ -21,7 +21,7 @@ extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 pub mod common;
 
diff --git a/pool/tests/coinbase_maturity.rs b/pool/tests/coinbase_maturity.rs
index 67dca51b8..3bfc12855 100644
--- a/pool/tests/coinbase_maturity.rs
+++ b/pool/tests/coinbase_maturity.rs
@@ -21,7 +21,7 @@ extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 pub mod common;
 
diff --git a/pool/tests/common/mod.rs b/pool/tests/common/mod.rs
index c65fe5d12..e766412da 100644
--- a/pool/tests/common/mod.rs
+++ b/pool/tests/common/mod.rs
@@ -24,7 +24,7 @@ extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::sync::{Arc, RwLock};
diff --git a/pool/tests/transaction_pool.rs b/pool/tests/transaction_pool.rs
index 009eddab1..beb4e3924 100644
--- a/pool/tests/transaction_pool.rs
+++ b/pool/tests/transaction_pool.rs
@@ -21,7 +21,7 @@ extern crate grin_util as util;
 extern crate grin_wallet as wallet;
 
 extern crate rand;
-extern crate time;
+extern crate chrono;
 
 pub mod common;
 
diff --git a/servers/Cargo.toml b/servers/Cargo.toml
index 3704d3ae0..478aea6f1 100644
--- a/servers/Cargo.toml
+++ b/servers/Cargo.toml
@@ -15,7 +15,7 @@ slog = { version = "~2.2", features = ["max_level_trace", "release_max_level_tra
 serde = "1"
 serde_derive = "1"
 serde_json = "1"
-time = "0.1"
+chrono = "0.4.4"
 bufstream = "~0.1"
 jsonrpc-core = "~8.0"
 
diff --git a/servers/src/grin/dandelion_monitor.rs b/servers/src/grin/dandelion_monitor.rs
index a531d09c2..d03af023c 100644
--- a/servers/src/grin/dandelion_monitor.rs
+++ b/servers/src/grin/dandelion_monitor.rs
@@ -17,7 +17,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, RwLock};
 use std::thread;
 use std::time::Duration;
-use time::now_utc;
+use chrono::prelude::{Utc};
 
 use core::core::hash::Hashed;
 use core::core::transaction;
@@ -200,7 +200,7 @@ fn process_expired_entries<T>(
 where
 	T: BlockChain + Send + Sync + 'static,
 {
-	let now = now_utc().to_timespec().sec;
+	let now = Utc::now().timestamp();
 	let embargo_sec = dandelion_config.embargo_secs.unwrap() + rand::thread_rng().gen_range(0, 31);
 	let cutoff = now - embargo_sec as i64;
 
@@ -211,7 +211,7 @@ where
 			.stempool
 			.entries
 			.iter()
-			.filter(|x| x.tx_at.sec < cutoff)
+			.filter(|x| x.tx_at.timestamp() < cutoff)
 		{
 			debug!(
 				LOGGER,
diff --git a/servers/src/grin/seed.rs b/servers/src/grin/seed.rs
index 15bdf08f7..d98fae8b6 100644
--- a/servers/src/grin/seed.rs
+++ b/servers/src/grin/seed.rs
@@ -22,8 +22,9 @@ use std::str;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{mpsc, Arc};
 use std::thread;
-use std::time::Duration;
-use time::{self, now_utc};
+use std::time;
+use chrono::prelude::{Utc};
+use chrono::Duration;
 
 use hyper;
 
@@ -56,11 +57,11 @@ pub fn connect_and_monitor(
 			// check seeds first
 			connect_to_seeds(peers.clone(), tx.clone(), seed_list);
 
-			let mut prev = time::now_utc() - time::Duration::seconds(60);
+			let mut prev = Utc::now() - Duration::seconds(60);
 			loop {
-				let current_time = time::now_utc();
+				let current_time = Utc::now();
 
-				if current_time - prev > time::Duration::seconds(20) {
+				if current_time - prev > Duration::seconds(20) {
 					// try to connect to any address sent to the channel
 					listen_for_addrs(peers.clone(), p2p_server.clone(), capabilities, &rx);
 
@@ -77,7 +78,7 @@ pub fn connect_and_monitor(
 					prev = current_time;
 				}
 
-				thread::sleep(Duration::from_secs(1));
+				thread::sleep(time::Duration::from_secs(1));
 
 				if stop.load(Ordering::Relaxed) {
 					break;
@@ -101,7 +102,7 @@ fn monitor_peers(
 	for x in peers.all_peers() {
 		match x.flags {
 			p2p::State::Banned => {
-				let interval = now_utc().to_timespec().sec - x.last_banned;
+				let interval = Utc::now().timestamp() - x.last_banned;
 				// Unban peer
 				if interval >= config.ban_window() {
 					peers.unban_peer(&x.addr);
@@ -166,7 +167,7 @@ fn update_dandelion_relay(peers: Arc<p2p::Peers>, dandelion_config: DandelionCon
 		peers.update_dandelion_relay();
 	} else {
 		for last_added in dandelion_relay.keys() {
-			let dandelion_interval = now_utc().to_timespec().sec - last_added;
+			let dandelion_interval = Utc::now().timestamp() - last_added;
 			if dandelion_interval >= dandelion_config.relay_secs.unwrap() as i64 {
 				debug!(LOGGER, "monitor_peers: updating expired dandelion relay");
 				peers.update_dandelion_relay();
diff --git a/servers/src/grin/sync.rs b/servers/src/grin/sync.rs
index 2ba04c648..c5e99f5e8 100644
--- a/servers/src/grin/sync.rs
+++ b/servers/src/grin/sync.rs
@@ -14,9 +14,10 @@
 
 use std::sync::Arc;
 use std::sync::atomic::{AtomicBool, Ordering};
-use std::time::Duration;
+use std::time;
 use std::{cmp, thread};
-use time;
+use chrono::prelude::{DateTime, Utc};
+use chrono::Duration;
 
 use chain;
 use common::types::{Error, SyncState, SyncStatus};
@@ -85,7 +86,7 @@ pub fn run_sync(
 				awaiting_peers.store(true, Ordering::Relaxed);
 				let mut n = 0;
 				while peers.more_work_peers().len() < 4 && n < wait_secs {
-					thread::sleep(Duration::from_secs(1));
+					thread::sleep(time::Duration::from_secs(1));
 					n += 1;
 				}
 				awaiting_peers.store(false, Ordering::Relaxed);
@@ -146,7 +147,7 @@ pub fn run_sync(
 					sync_state.update(SyncStatus::NoSync);
 				}
 
-				thread::sleep(Duration::from_secs(1));
+				thread::sleep(time::Duration::from_secs(1));
 
 				if stop.load(Ordering::Relaxed) {
 					break;
@@ -399,15 +400,15 @@ fn get_locator_heights(height: u64) -> Vec<u64> {
 
 // Utility struct to group what information the main sync loop has to track
 struct SyncInfo {
-	prev_body_sync: (time::Tm, u64),
-	prev_header_sync: (time::Tm, u64),
-	prev_fast_sync: Option<time::Tm>,
+	prev_body_sync: (DateTime<Utc>, u64),
+	prev_header_sync: (DateTime<Utc>, u64),
+	prev_fast_sync: Option<DateTime<Utc>>,
 	highest_height: u64,
 }
 
 impl SyncInfo {
 	fn new() -> SyncInfo {
-		let now = time::now_utc();
+		let now = Utc::now();
 		SyncInfo {
 			prev_body_sync: (now.clone(), 0),
 			prev_header_sync: (now.clone(), 0),
@@ -417,11 +418,11 @@ impl SyncInfo {
 	}
 
 	fn header_sync_due(&mut self, header_head: &chain::Tip) -> bool {
-		let now = time::now_utc();
+		let now = Utc::now();
 		let (prev_ts, prev_height) = self.prev_header_sync;
 
 		if header_head.height >= prev_height + (p2p::MAX_BLOCK_HEADERS as u64) - 4
-			|| now - prev_ts > time::Duration::seconds(10)
+			|| now - prev_ts > Duration::seconds(10)
 		{
 			self.prev_header_sync = (now, header_head.height);
 			return true;
@@ -430,10 +431,10 @@ impl SyncInfo {
 	}
 
 	fn body_sync_due(&mut self, head: &chain::Tip) -> bool {
-		let now = time::now_utc();
+		let now = Utc::now();
 		let (prev_ts, prev_height) = self.prev_body_sync;
 
-		if head.height >= prev_height + 96 || now - prev_ts > time::Duration::seconds(5) {
+		if head.height >= prev_height + 96 || now - prev_ts > Duration::seconds(5) {
 			self.prev_body_sync = (now, head.height);
 			return true;
 		}
@@ -443,7 +444,7 @@ impl SyncInfo {
 	// For now this is a one-time thing (it can be slow) at initial startup.
 	fn fast_sync_due(&mut self) -> bool {
 		if let None = self.prev_fast_sync {
-			let now = time::now_utc();
+			let now = Utc::now();
 			self.prev_fast_sync = Some(now);
 			true
 		} else {
diff --git a/servers/src/lib.rs b/servers/src/lib.rs
index 6b26a06e8..d81a4d878 100644
--- a/servers/src/lib.rs
+++ b/servers/src/lib.rs
@@ -33,7 +33,7 @@ extern crate serde_derive;
 extern crate serde_json;
 #[macro_use]
 extern crate slog;
-extern crate time;
+extern crate chrono;
 
 extern crate grin_api as api;
 extern crate grin_chain as chain;
diff --git a/servers/src/mining/mine_block.rs b/servers/src/mining/mine_block.rs
index f4d408b37..7794724db 100644
--- a/servers/src/mining/mine_block.rs
+++ b/servers/src/mining/mine_block.rs
@@ -20,7 +20,7 @@ use rand::{self, Rng};
 use std::sync::{Arc, RwLock};
 use std::thread;
 use std::time::Duration;
-use time;
+use chrono::prelude::{DateTime, NaiveDateTime, Utc};
 
 use chain;
 use common::adapters::PoolToChainAdapter;
@@ -139,8 +139,8 @@ fn build_block(
 	// prepare the block header timestamp
 	let head = chain.head_header()?;
 
-	let mut now_sec = time::get_time().sec;
-	let head_sec = head.timestamp.to_timespec().sec;
+	let mut now_sec = Utc::now().timestamp();
+	let head_sec = head.timestamp.timestamp();
 	if now_sec <= head_sec {
 		now_sec = head_sec + 1;
 	}
@@ -172,7 +172,7 @@ fn build_block(
 
 	let mut rng = rand::OsRng::new().unwrap();
 	b.header.nonce = rng.gen();
-	b.header.timestamp = time::at_utc(time::Timespec::new(now_sec, 0));
+	b.header.timestamp = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(now_sec, 0), Utc);;
 
 	let b_difficulty = (b.header.total_difficulty.clone() - head.total_difficulty.clone()).to_num();
 	debug!(
diff --git a/servers/src/mining/stratumserver.rs b/servers/src/mining/stratumserver.rs
index d7a4a4366..2f1cb7646 100644
--- a/servers/src/mining/stratumserver.rs
+++ b/servers/src/mining/stratumserver.rs
@@ -23,7 +23,7 @@ use std::net::{TcpListener, TcpStream};
 use std::sync::{Arc, Mutex, RwLock};
 use std::time::{Duration, SystemTime};
 use std::{cmp, thread};
-use time;
+use chrono::prelude::{Utc};
 
 use chain;
 use common::adapters::PoolToChainAdapter;
@@ -711,7 +711,7 @@ impl StratumServer {
 			// or We are rebuilding the current one to include new transactions
 			// and we're not synching
 			// and there is at least one worker connected
-			if (current_hash != latest_hash || time::get_time().sec >= deadline) && !mining_stopped
+			if (current_hash != latest_hash || Utc::now().timestamp() >= deadline) && !mining_stopped
 				&& num_workers > 0
 			{
 				let mut wallet_listener_url: Option<String> = None;
@@ -741,7 +741,7 @@ impl StratumServer {
 					self.current_difficulty,
 				);
 				// set a new deadline for rebuilding with fresh transactions
-				deadline = time::get_time().sec + attempt_time_per_block as i64;
+				deadline = Utc::now().timestamp() + attempt_time_per_block as i64;
 
 				{
 					let mut stratum_stats = stratum_stats.write().unwrap();
diff --git a/servers/src/mining/test_miner.rs b/servers/src/mining/test_miner.rs
index 323d2faa1..6dde5e955 100644
--- a/servers/src/mining/test_miner.rs
+++ b/servers/src/mining/test_miner.rs
@@ -1,3 +1,4 @@
+
 // Copyright 2018 The Grin Developers
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +20,7 @@
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{Arc, RwLock};
-use time;
+use chrono::prelude::{Utc};
 
 use chain;
 use common::adapters::PoolToChainAdapter;
@@ -81,7 +82,7 @@ impl Miner {
 	) -> Option<Proof> {
 		// look for a pow for at most 2 sec on the same block (to give a chance to new
 		// transactions) and as long as the head hasn't changed
-		let deadline = time::get_time().sec + attempt_time_per_block as i64;
+		let deadline = Utc::now().timestamp() + attempt_time_per_block as i64;
 
 		debug!(
 			LOGGER,
@@ -96,7 +97,7 @@ impl Miner {
 		let mut iter_count = 0;
 
 		let mut sol = None;
-		while head.hash() == *latest_hash && time::get_time().sec < deadline {
+		while head.hash() == *latest_hash && Utc::now().timestamp() < deadline {
 			if let Ok(proof) = cuckoo::Miner::new(
 				&b.header,
 				consensus::EASINESS,
diff --git a/src/bin/grin.rs b/src/bin/grin.rs
index 511cd680b..914b54e16 100644
--- a/src/bin/grin.rs
+++ b/src/bin/grin.rs
@@ -24,7 +24,7 @@ extern crate serde;
 extern crate serde_json;
 #[macro_use]
 extern crate slog;
-extern crate time;
+extern crate chrono;
 
 extern crate grin_api as api;
 extern crate grin_config as config;
diff --git a/src/bin/tui/ui.rs b/src/bin/tui/ui.rs
index e53fc781b..e4d6b79ed 100644
--- a/src/bin/tui/ui.rs
+++ b/src/bin/tui/ui.rs
@@ -17,7 +17,7 @@
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::{mpsc, Arc};
-use time;
+use chrono::prelude::{Utc};
 
 use cursive::direction::Orientation;
 use cursive::theme::BaseColor::{Black, Blue, Cyan, White};
@@ -167,7 +167,7 @@ impl Controller {
 	/// Run the controller
 	pub fn run(&mut self, server: Arc<Server>, running: Arc<AtomicBool>) {
 		let stat_update_interval = 1;
-		let mut next_stat_update = time::get_time().sec + stat_update_interval;
+		let mut next_stat_update = Utc::now().timestamp() + stat_update_interval;
 		while self.ui.step() {
 			if !running.load(Ordering::SeqCst) {
 				warn!(LOGGER, "Received SIGINT (Ctrl+C).");
@@ -188,10 +188,10 @@ impl Controller {
 				}
 			}
 
-			if time::get_time().sec > next_stat_update {
+			if Utc::now().timestamp() > next_stat_update {
 				let stats = server.get_server_stats().unwrap();
 				self.ui.ui_tx.send(UIMessage::UpdateStatus(stats)).unwrap();
-				next_stat_update = time::get_time().sec + stat_update_interval;
+				next_stat_update = Utc::now().timestamp() + stat_update_interval;
 			}
 		}
 	}
diff --git a/store/Cargo.toml b/store/Cargo.toml
index 969d5cb03..bb1ebec90 100644
--- a/store/Cargo.toml
+++ b/store/Cargo.toml
@@ -22,5 +22,5 @@ grin_core = { path = "../core" }
 grin_util = { path = "../util" }
 
 [dev-dependencies]
-time = "0.1"
+chrono = "0.4.4"
 rand = "0.3"
diff --git a/store/tests/pmmr.rs b/store/tests/pmmr.rs
index fe322e2b1..9def3375e 100644
--- a/store/tests/pmmr.rs
+++ b/store/tests/pmmr.rs
@@ -16,10 +16,11 @@ extern crate croaring;
 extern crate env_logger;
 extern crate grin_core as core;
 extern crate grin_store as store;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 
+use chrono::prelude::{Utc};
 use croaring::Bitmap;
 
 use core::core::pmmr::{Backend, PMMR};
@@ -722,8 +723,8 @@ fn setup(tag: &str) -> (String, Vec<TestElem>) {
 		Ok(_) => println!("Initializing env logger"),
 		Err(e) => println!("env logger already initialized: {:?}", e),
 	};
-	let t = time::get_time();
-	let data_dir = format!("./target/tmp/{}.{}-{}", t.sec, t.nsec, tag);
+	let t = Utc::now();
+	let data_dir = format!("./target/tmp/{}.{}-{}", t.timestamp(), t.timestamp_subsec_nanos(), tag);
 	fs::create_dir_all(data_dir.clone()).unwrap();
 
 	let mut elems = vec![];
diff --git a/store/tests/rm_log_perf.rs b/store/tests/rm_log_perf.rs
index 639ac8a54..25797c10a 100644
--- a/store/tests/rm_log_perf.rs
+++ b/store/tests/rm_log_perf.rs
@@ -16,10 +16,11 @@ extern crate croaring;
 extern crate env_logger;
 extern crate grin_core as core;
 extern crate grin_store as store;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::time::{Duration, Instant};
+use chrono::prelude::{Utc};
 
 use store::rm_log::RemoveLog;
 
@@ -97,8 +98,7 @@ fn test_rm_log_performance() {
 
 fn setup(test_name: &str) -> (RemoveLog, String) {
 	let _ = env_logger::init();
-	let t = time::get_time();
-	let data_dir = format!("./target/{}-{}", test_name, t.sec);
+	let data_dir = format!("./target/{}-{}", test_name, Utc::now().timestamp());
 	fs::create_dir_all(data_dir.clone()).unwrap();
 	let rm_log = RemoveLog::open(format!("{}/{}", data_dir, "rm_log.bin")).unwrap();
 	(rm_log, data_dir)
diff --git a/store/tests/utxo_set_perf.rs b/store/tests/utxo_set_perf.rs
index 9d2e566dc..7543c60f2 100644
--- a/store/tests/utxo_set_perf.rs
+++ b/store/tests/utxo_set_perf.rs
@@ -16,10 +16,11 @@ extern crate croaring;
 extern crate env_logger;
 extern crate grin_core as core;
 extern crate grin_store as store;
-extern crate time;
+extern crate chrono;
 
 use std::fs;
 use std::time::{Duration, Instant};
+use chrono::prelude::{Utc};
 
 use croaring::Bitmap;
 
@@ -98,8 +99,7 @@ fn test_leaf_set_performance() {
 
 fn setup(test_name: &str) -> (LeafSet, String) {
 	let _ = env_logger::init();
-	let t = time::get_time();
-	let data_dir = format!("./target/{}-{}", test_name, t.sec);
+	let data_dir = format!("./target/{}-{}", test_name, Utc::now().timestamp());
 	fs::create_dir_all(data_dir.clone()).unwrap();
 	let leaf_set = LeafSet::open(format!("{}/{}", data_dir, "utxo.bin")).unwrap();
 	(leaf_set, data_dir)
diff --git a/wallet/Cargo.toml b/wallet/Cargo.toml
index 075bb76ff..d217cf7b6 100644
--- a/wallet/Cargo.toml
+++ b/wallet/Cargo.toml
@@ -26,7 +26,7 @@ tokio-core = "0.1"
 tokio-retry = "0.1"
 uuid = { version = "0.6", features = ["serde", "v4"] }
 urlencoded = "0.5"
-chrono = { version = "0.4", features = ["serde"] }
+chrono = { version = "0.4.4", features = ["serde"] }
 
 grin_api = { path = "../api" }
 grin_core = { path = "../core" }
@@ -37,4 +37,3 @@ grin_util = { path = "../util" }
 [dev-dependencies]
 grin_chain = { path = "../chain" }
 grin_store = { path = "../store" }
-time = "0.1"
diff --git a/wallet/tests/common/mod.rs b/wallet/tests/common/mod.rs
index 845ad2da5..1a71269f3 100644
--- a/wallet/tests/common/mod.rs
+++ b/wallet/tests/common/mod.rs
@@ -19,9 +19,10 @@ extern crate grin_core as core;
 extern crate grin_keychain as keychain;
 extern crate grin_wallet as wallet;
 extern crate serde_json;
-extern crate time;
+extern crate chrono;
 
 use std::sync::{Arc, Mutex};
+use chrono::Duration;
 
 use chain::Chain;
 use core::core::{OutputFeatures, OutputIdentifier, Transaction};
@@ -75,7 +76,7 @@ pub fn add_block_with_reward(chain: &Chain, txs: Vec<&Transaction>, reward: CbDa
 		difficulty.clone(),
 		(output, kernel),
 	).unwrap();
-	b.header.timestamp = prev.timestamp + time::Duration::seconds(60);
+	b.header.timestamp = prev.timestamp + Duration::seconds(60);
 	chain.set_txhashset_roots(&mut b, false).unwrap();
 	pow::pow_size(
 		&mut b.header,
diff --git a/wallet/tests/transaction.rs b/wallet/tests/transaction.rs
index 4be68e6d8..fb6f4f214 100644
--- a/wallet/tests/transaction.rs
+++ b/wallet/tests/transaction.rs
@@ -22,7 +22,7 @@ extern crate rand;
 #[macro_use]
 extern crate slog;
 extern crate serde;
-extern crate time;
+extern crate chrono;
 extern crate uuid;
 
 mod common;