I have a time span string as
1.21:00:00
it means 45 hours and i need it as
45:00:00
and i use following method from
Need only HH:MM:SS in time span string
it works perfectly for this above problem but when i change the string as
1.21:30:00
then mentioned code return me one hour more than actual time. in this case it return me 46:29:00 but actual that i need is 45:29:00.
I am using c#
EDIT
public Tuple<string,string> Calculate_Hours(DateTime strt, DateTime end)
{
TimeSpan wrkhrs = new TimeSpan(0, 0, 0);
TimeSpan exthrs=new TimeSpan(0,0,0);
cmd = new SqlCommand("select * from vw_Rept_Attend where UserID ='"+Convert.ToInt32 (cmbEmp.SelectedValue)+"' and convert(date,AtnDate) between '"+strt.Date+"' and '"+end.Date+"'",conn);
conn.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr["WorkHrs"].ToString().Length>0)
wrkhrs=wrkhrs.Add(Convert.ToDateTime(dr["WorkHrs"].ToString()).TimeOfDay);
// exthrs = exthrs.Add(Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay);
if (!dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
{
exthrs = exthrs.Add(Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay);
}
else if (dr["ExtraHrs"].ToString().Contains("-") && dr["ExtraHrs"].ToString().Length > 0)
{
//int index = dr["ExtraHrs"].ToString().LastIndexOf('-');
//string rhs = dr["ExtraHrs"].ToString().Substring(index + 1);
string ext = dr["ExtraHrs"].ToString().Substring(dr["ExtraHrs"].ToString().LastIndexOf("-") +1);
//TimeSpan test = Convert.ToDateTime(dr["ExtraHrs"].ToString()).TimeOfDay.Negate();
exthrs = exthrs.Subtract(Convert.ToDateTime(ext).TimeOfDay);
}
}
conn.Close();
dr.Close();
// string tst = exthrs.ToString().Substring(exthrs.ToString().LastIndexOf("-") + 1);
// wrkhrs.ToString();
// exthrs.ToString();
var val1 = TimeSpan.Parse(wrkhrs.ToString());
string val3= string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(wrkhrs.ToString()).TotalHours), TimeSpan.Parse(wrkhrs.ToString()));
var val2=TimeSpan.Parse(exthrs.ToString());
string val4=string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(exthrs.ToString()).TotalHours), TimeSpan.Parse(exthrs.ToString()));
return new Tuple<string, string>(string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(wrkhrs.ToString()).TotalHours), TimeSpan.Parse(wrkhrs.ToString())), string.Format("{0}:{1:mm}:{1:ss}", Math.Floor(TimeSpan.Parse(exthrs.ToString()).TotalHours), TimeSpan.Parse(exthrs.ToString())));
// MessageBox.Show(wrkhrs.ToString()+exthrs.ToString());
}
this is what i did yet.
I'm not sure if i got it since your expected result is strange. You add 30 minutes but expect 29 minutes in the result string? If i ignore that this should work:
var ts = TimeSpan.Parse("1.21:30:00");
string result = string.Format("{0:00}:{1:00}:{2:00}", (int)ts.TotalHours, ts.Minutes, ts.Seconds);
Returns: 45:30:00
You can use Math.Abs if you want to handle negative timespans:
String.Format("{0:00}:{1:00}:{2:00}", (int)ts.TotalHours, Math.Abs(ts.Minutes), Math.Abs(ts.Seconds));
Related
Hey guys im using Npgsql and need to pass parameters to my PostgreSQL stored procedure
my stored procedure expecting Date for my first two parameters:
SELECT wpv.avail_pro_failedbattry_error_powerconv(
<date>,
<date>,
<character varying>,
<character varying>,
<character varying>
);
so i need to pass date parameters :
NpgsqlDateTime DateFrom = NpgsqlDateTime.Parse(dtFrom);
NpgsqlDateTime DateTo = NpgsqlDateTime.Parse(dtTo);
NpgsqlParameter p0 = new NpgsqlParameter("#drfrom", dtFrom);
NpgsqlParameter p1 = new NpgsqlParameter("#dtto",dtTo);
NpgsqlParameter p2 = new NpgsqlParameter("#regionalmanager", regionalManager);
NpgsqlParameter p3 = new NpgsqlParameter("#serviceunder", service_under);
NpgsqlParameter p4 = new NpgsqlParameter("#supervisor", supervisor);
var x = _db.dataInGlance.FromSqlRaw(#"SELECT * from wpv.avail_pro_failedbattry_error_powerconv(#drfrom,#dtto,#regionalmanager,#serviceunder,#supervisor)
res (o_availability double precision, o_production double precision,o_numberofturbines integer, o_errors_disabled integer,o_failed_battery integer,o_power integer,o_crew_present text)",p0,p1,p2,p3,p4
).ToList();
dtfrom and dtto are string date format which is:
dtFrom="2020/07/03"
dtTo="2020/07/07"
but it gives me an error on the line
NpgsqlDateTime DateFrom = NpgsqlDateTime.Parse(dtFrom);
that the format is not correct!any help?
Looking at the source:
NpgsqlDateTime
which calls NpgsqlDate
along with Timespan.Parse() which seems mandatory.
Since you are not using a time, you could use NpgsqlDate.Parse() instead.
The source seems to be expecting the following format for date parsing: yyyy-MM-dd
So if you meant the 3rd of July
dtFrom="2020-07-03"
but if you meant the 7th of March
dtFrom="2020-03-07"
Source code:
try {
var idx = str.IndexOf('-');
if (idx == -1) {
throw new FormatException();
}
var year = int.Parse(str.Substring(0, idx));
var idxLast = idx + 1;
if ((idx = str.IndexOf('-', idxLast)) == -1) {
throw new FormatException();
}
var month = int.Parse(str.Substring(idxLast, idx - idxLast));
idxLast = idx + 1;
if ((idx = str.IndexOf(' ', idxLast)) == -1) {
idx = str.Length;
}
var day = int.Parse(str.Substring(idxLast, idx - idxLast));
if (str.Contains("BC")) {
year = -year;
}
return new NpgsqlDate(year, month, day);
} catch (OverflowException) {
throw;
} catch (Exception) {
throw new FormatException();
}
Additionally if NpgsqlDate.Parse is not accepted, you could use NpgsqlDateTime.Parse with the time part set to zero.
NpgsqlDateTime.Parse("2020-07-03 00:00")
Is there a way to convert a yyyy/ddd string to Date in C#?
For example 2019003 is January 3, 2019.
Also to validate if the string is yyyy/ddd format.
Kindly help
You could make a TryParse method like this:
public static bool TryParseSpecialDate(string dateString, out DateTime parsedDate)
{
parsedDate = DateTime.MinValue;
// parse yyyy/DDD into 2 separate capture groups
var match = Regex.Match(dateString ?? string.Empty, #"^(\d{4})/(\d{3})$");
if (!match.Success)
{
return false;
}
// Create a date for yyyy/01/01
var yearDate = new DateTime(int.Parse(match.Groups[1].Value), 1, 1);
var dayOfYear = int.Parse(match.Groups[2].Value);
if (dayOfYear < 1 || dayOfYear > 366)
{
return false;
}
// Add the required number of days
var result = yearDate.AddDays(dayOfYear - 1);
// Check that it's the same year (so that 2019/888 won't work, or 366 in a non leap year)
if (result.Year != yearDate.Year)
{
return false;
}
// Set the date and return it
parsedDate = result;
return true;
}
I've used regex (I didn't need to but it seemed easier, feel free to replace it with string operations instead). This then starts from January in the desired year, and adds the number of days to it.
Usage:
bool success = DateTimeHelpers.TryParseSpecialDate("2019/354", out tmp);
Output will be 2019/12/20
Try it online
You can probably do this:
string julianDate = "2019003";
int year = Convert.ToInt32(julianDate.Substring(0, 4));
int dayOfYear = Convert.ToInt32(julianDate.Substring(4));
DateTime dateTime = new DateTime(year-1, 12, 18, new JulianCalendar());
dateTime = dateTime.AddDays(dayOfYear);
This should return the desired date.
Reference:
I want to covert julian date(YYJJJ format) to any normal date format(MMDDYY) using c#. Is there any defined function for that?
Here's method to achieve that:
public DateTime ParseDateString(string strDt)
{
// validate string, pattern explanation:
// \d - match sigle digit
// ^ - match beginning of a string
// $ - match end of a string
// /? - match zero or one /
if(! Regex.Match(strDt, #"^\d\d\d\d/?\d\d\d$").Success)
throw new ArgumentException("Invalid string");
// get rid of a optional /
strDt = strDt.Replace("/", "");
var days = int.Parse(dt.Substring(4));
var year = int.Parse(dt.Substring(0, 4));
var date = new DateTime(year, 1, 1);
return date.AddDays(days - 1);
}
I want to be able to calculate the time in hours and minutes elapsed between, say, 12:35pm 02/13/2016 to 1:45pm 02/14/2016, but can't figure out the correct format to input it.
EDIT: Should add that the span between the times will be stored in an arraylist, one span per customer.
Basically, you need something like this:
var dateA = new DateTime(2016,2,13,12,35,0);
var dateB = new DateTime(2016,2,14,1,45,0);
var timespan = dateB - dateA;
var hours = timespan.Hours;
bar minutes = timespan.Minutes;
Here's how I would go about it:
Func<string, DateTime?> tryParse = t =>
{
DateTime output;
if (DateTime.TryParseExact(
t,
new [] { "h:mmtt MM/dd/yyyy" },
System.Globalization.CultureInfo.CurrentCulture,
System.Globalization.DateTimeStyles.AssumeLocal,
out output))
{
return output;
}
return null;
};
var dt1 = tryParse("12:35pm 02/13/2016");
var dt2 = tryParse("1:45pm 02/14/2016");
TimeSpan? ts = null;
if (dt1.HasValue && dt2.HasValue)
{
ts = dt2.Value.Subtract(dt1.Value);
}
if (ts.HasValue)
{
Console.WriteLine(
String.Format(
"{0} hours & {1} minutes",
ts.Value.Hours,
ts.Value.Minutes));
}
I have a string called value with 1899-12-30 01:30:00
I want to get 01:30 into a seperate string, I have tried to use substring but it keeps giving me an error that the startindex cannot be less than zero, can someone tell me what im doing wrong?
using (OleDbDataAdapter oda = new OleDbDataAdapter("SELECT * FROM [" + sheet1 + "]", excel_con))
{
oda.Fill(dtExcelData);
}
excel_con.Close();
if (dtExcelData.Rows.Count > 0)
{
foreach (DataRow rw in dtExcelData.Rows)
{
//Creates StaffID
rw["StaffID"] = "00" + rw["Host Key of Staff"].ToString();
//Get duration out of DateTime
string Value = rw["Taught Periods Distinct as duration"].ToString();
string Duration = Value.Substring(Value.Length - 10, 5);
rw["Taught Periods Distinct as duration"] = Duration.ToString();
}
}
Debugging it says:
Duration = "01:30" Type String
Value = "30/12/1989 01:30:00" Type String
Value.Length = 19 Type int
rw["Taught periods as distinct as duration"] = "30/12/1989 01:30:00" Type object {string}
First add a break point and see the value of Value, it seems like there is invalid value in your variable.
To extract out 01:30 into a separate string, a better approach would be to use DateTime parsing. Because your string is a valid DateTime value. Use
DateTime parsedDateTime;
string Duration = null;
if (!DateTime.TryParseExact("1899-12-30 01:30:00", //or rw["Taught Periods Distinct as duration"].ToString();
"yyyy-MM-dd HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out parsedDateTime))
{
Console.WriteLine("Invalid date");
}
else
{
Duration = parsedDateTime.ToString("HH:mm", CultureInfo.InvariantCulture);
}
In fact, you want to extract the time (hour + minute) from your date.
For this, I recommend not to do string conversions. Instead, better use a more direct approach by directly using DateTime, like this:
DateTime Value = rw["Taught Periods Distinct as duration"];
rw["Taught Periods Distinct as duration"] = Value.TimeOfDay ;
this works:
string Value = "Taught Periods Distinct as duration".ToString();
string Duration = Value.Substring(Value.Length - 10, 5);
and also:
string Value2 = "1899-12-30 01:30:00";
string Duration2 = Value2.Substring(Value2.Length - 10, 5);
I have a problem calculating difference between two timestamps, when minutes are represented with 3 digits, e.g. 180:22 = 180 minutes and 22 seconds.
So, can you help me how can I get difference between timestamps like:
180:22 and 122:11
or
232:21 and 31:34
etc.
UPDATE: I need to get difference between two times, defined as strings. What makes a problem is that minutes in those strings (times) are larger than 60, and they are over the limit. So I need to know how to find difference like in above examples (180:22 and 122:11, and 232:21 and 31:34)
Use System.TimeSpan structures:
var seconds=(new TimeSpan(0, 180, 22)-new TimeSpan(0, 122, 11)).TotalSeconds;
var minutes=(new TimeSpan(0, 232, 21)-new TimeSpan(0, 31, 34)).TotalMinutes;
Here's a class that will do this stuff:
public class CrazyTime
{
public TimeSpan TimeSpanRepresentation { get; set; }
public CrazyTime(TimeSpan timeSpan)
{
this.TimeSpanRepresentation = timeSpan;
}
public CrazyTime(string crazyTime)
{
// No error checking. Add if so desired
var pieces = crazyTime.Split(new[] { ':' });
var minutes = int.Parse(pieces[0]);
var seconds = int.Parse(pieces[1]);
TimeSpanRepresentation = new TimeSpan(0, minutes, seconds);
}
public static CrazyTime operator-(CrazyTime left, CrazyTime right)
{
var newValue = left.TimeSpanRepresentation - right.TimeSpanRepresentation;
return new CrazyTime(newValue);
}
public override string ToString()
{
// How should negative Values look?
return ((int)Math.Floor(TimeSpanRepresentation.TotalMinutes)).ToString() + ":" + TimeSpanRepresentation.Seconds.ToString();
}
}
Here's how it might be used:
var a = new CrazyTime("123:22");
var b = new CrazyTime("222:11");
var c = b - a;
Console.WriteLine(c);
This works:
string time1 = "180:22";
string time2 = "122:11";
TimeSpan span1 = getTimespan(time1);
TimeSpan span2 = getTimespan(time2);
TimeSpan diff = span1 - span2;
getTimespan just has to correctly parse the string. I decided on Regex to do that, but you could go any route, particularly if the delimiter ":" isn't ever going to change.
private static TimeSpan getTimespan(string time1)
{
Regex reg = new Regex(#"\d+");
MatchCollection matches = reg.Matches(time1);
if (matches.Count == 2)
{
int minutes = int.Parse(matches[0].Value);
int seconds = int.Parse(matches[1].Value);
return new TimeSpan(0, minutes, seconds);
}
return TimeSpan.Zero;
}