tradingbot/src/time_checking_team.rs

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(),
}
}
}