145 lines
5.4 KiB
Rust
145 lines
5.4 KiB
Rust
use crate::database_control::*;
|
|
use chrono::TimeZone;
|
|
use reqwest::{Client, ClientBuilder};
|
|
use serde::Deserialize;
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
use tokio::{join, time::*};
|
|
|
|
// structure for checking server time and local time
|
|
#[derive(Debug)]
|
|
pub struct UserTime {
|
|
pub server_epoch: u128, // server time in Unix Epoch Time
|
|
pub local_epoch: u128, // local time where the tradingbot is running in Unix Epoch Time.
|
|
pub epoch_difference: i64, // epoch difference from server time to local time in Unix Epoch Time. (can be used as RTT)
|
|
// positive value means server is leading to local, negative value means server is lagging to local.
|
|
server_ymdhs: String, // human-readable date form of server time in UTC (y: year, m: month, d: day, h: hour, s: second)
|
|
local_ymdhs: String, // human-readable date form of local time in UTC (y: year, m: month, d: day, h: hour, s: second)
|
|
last_server_epoch: u128, // the last server epoch until the server is turned off.
|
|
last_server_ymdhs: String, // the last server date until the server is turned off.
|
|
}
|
|
|
|
impl UserTime {
|
|
// make an instance and initialize fields
|
|
pub fn new() -> UserTime {
|
|
UserTime {
|
|
server_epoch: 0,
|
|
local_epoch: 0,
|
|
epoch_difference: 0,
|
|
server_ymdhs: String::new(),
|
|
local_ymdhs: String::new(),
|
|
last_server_epoch: 0,
|
|
last_server_ymdhs: String::from("----"),
|
|
}
|
|
}
|
|
|
|
// update all field in Time struct.
|
|
async fn update(
|
|
&mut self,
|
|
client: &Client,
|
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
let (servertime, localtime) = join!(Self::get_server_time(&client), Self::get_local_time());
|
|
self.server_epoch = servertime?;
|
|
self.local_epoch = localtime?;
|
|
self.epoch_difference =
|
|
Self::get_difference_time(self.server_epoch, self.local_epoch).await;
|
|
self.server_ymdhs = Self::convert_epoch_to_ymdhs(self.server_epoch);
|
|
self.local_ymdhs = Self::convert_epoch_to_ymdhs(self.local_epoch);
|
|
Ok(())
|
|
}
|
|
|
|
// to record the last server-on time when request doesn't work.
|
|
pub async fn update_last_server(&mut self) {
|
|
self.last_server_epoch = self.server_epoch;
|
|
if self.server_epoch == 0 {
|
|
self.last_server_ymdhs =
|
|
String::from("server has been shutdown before the bot was executed.");
|
|
} else {
|
|
self.last_server_ymdhs = self.server_ymdhs.clone();
|
|
}
|
|
}
|
|
|
|
async fn get_server_time(
|
|
client: &Client,
|
|
) -> Result<u128, Box<dyn std::error::Error + Send + Sync>> {
|
|
#[derive(Deserialize)]
|
|
struct ServerTime {
|
|
serverTime: u128,
|
|
}
|
|
let mut servertime = ServerTime { serverTime: 0 };
|
|
|
|
let response = client
|
|
.get("https://api.binance.com/api/v3/time")
|
|
.send()
|
|
.await?;
|
|
|
|
servertime = response.json::<ServerTime>().await?;
|
|
Ok(servertime.serverTime)
|
|
}
|
|
|
|
// function to get the current local time
|
|
async fn get_local_time() -> Result<u128, std::time::SystemTimeError> {
|
|
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
|
Ok(T) => Ok(T.as_millis()),
|
|
Err(E) => Err(E),
|
|
}
|
|
}
|
|
|
|
// function to get the difference time from the local to the server
|
|
async fn get_difference_time(servertime: u128, localtime: u128) -> i64 {
|
|
if servertime >= localtime {
|
|
(servertime - localtime) as i64
|
|
} else {
|
|
0 - ((localtime - servertime) as i64)
|
|
}
|
|
}
|
|
|
|
// function to convert Unix Epoch time of server to human-readable date in UTC
|
|
fn convert_epoch_to_ymdhs(epoch_time: u128) -> String {
|
|
let time_i64 = (epoch_time / 1000) as i64;
|
|
chrono::offset::Utc.timestamp(time_i64, 0).to_string()
|
|
}
|
|
}
|
|
|
|
// run time checking and store data into database.
|
|
pub async fn execute_time_check(
|
|
usertime: &mut UserTime,
|
|
client: &Client,
|
|
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|
usertime.update(&client).await?;
|
|
|
|
let table_name = String::from("time");
|
|
let mut record: Vec<(&str, &str)> = Vec::new();
|
|
let condition = vec![("id", "1")];
|
|
|
|
let server_epoch = usertime.server_epoch.to_string();
|
|
let local_epoch = usertime.local_epoch.to_string();
|
|
let epoch_difference = usertime.epoch_difference.to_string();
|
|
let last_server_epoch = usertime.last_server_epoch.to_string();
|
|
|
|
record.push(("server_epoch", server_epoch.as_str()));
|
|
record.push(("local_epoch", local_epoch.as_str()));
|
|
record.push(("epoch_difference", epoch_difference.as_str()));
|
|
record.push(("server_ymdhs", usertime.server_ymdhs.as_str()));
|
|
record.push(("local_ymdhs", usertime.local_ymdhs.as_str()));
|
|
record.push(("last_server_epoch", last_server_epoch.as_str()));
|
|
record.push(("last_server_ymdhs", usertime.last_server_ymdhs.as_str()));
|
|
|
|
update_record(&table_name, &record, &condition).await?;
|
|
// println!("time check 완료");
|
|
Ok(())
|
|
}
|
|
|
|
impl Clone for UserTime {
|
|
fn clone(&self) -> Self {
|
|
UserTime {
|
|
server_epoch: self.server_epoch,
|
|
local_epoch: self.local_epoch,
|
|
epoch_difference: self.epoch_difference,
|
|
server_ymdhs: self.last_server_ymdhs.clone(),
|
|
local_ymdhs: self.local_ymdhs.clone(),
|
|
last_server_epoch: self.last_server_epoch,
|
|
last_server_ymdhs: self.last_server_ymdhs.clone(),
|
|
}
|
|
}
|
|
}
|