How to paas time value from page.cs to ViewModel.
timevalue is string like "14h:15m"
Here I'm trying...
Page.cs
_model.StartTime = int.Parse(timevalue);
ViewModel
public DateTime StartTime { get; set; } = DateTime.Today;
public DateTime EndTime { get; set; }
public int Duration { get; set; }
private TimeSpan[] _StartTimeValues { get; set; }
private int _StartTimeIndex = -1;
public int StartTime
{
get { return _StartTime; }
set
{
_StartTimeIndex = value;
if (value >= 0)
{
StartTime =StartTime.Date.Add(_StartTimeValues[value]);
EndTime = StartTime.AddMinutes(Duration);
}
OnPropertyChanged(nameof(StartTime));
}
}
At first, please change the _StartTimeIndex's type to SpanTime, because the TimeDate.Add need a parameter type of SpanTime. Such as:
string time = "12h45m";
char[] hourandminute = new char[] { 'h', 'm' };
string[] temp = time.Split(hourandminute);
int hour = int.Parse(temp[0]);
int minutes = int.Parse(temp[1]);
TimeSpan timeSpan = new TimeSpan(hour, minutes, 0);
Related
I have this model in my ASP.NET Core Web API:
Models:
namespace Core.Models
{
public class Mandate : EntityBase
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int? PaymentFrequency { get; set; } //1=Monthly, 2=Quarterly, 3=Yearly
public int? PaymentCount { get; set; }
public decimal Amount { get; set; }
}
}
ViewModel:
public class MandateVM
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int? PaymentFrequency { get; set; } //1=Monthly, 2=Quarterly, 3=Yearly
public decimal Amount { get; set; }
}
I have written some helpers that gets TotalMonth, TotalQuarter and TotalYear from StartDate and EndDate as show below:
namespace Infrastructure.Helpers
{
public static class ConstantHelper
{
private static IConfiguration Configuration { get; set; }
public static int GetTotalMonth(DateTime startDate, DateTime endDate)
{
int totalMonth = 12 * (startDate.Year - endDate.Year) + startDate.Month - endDate.Month;
return Convert.ToInt32(Math.Abs(totalMonth));
}
public static int GetTotalQuarter(DateTime startDate, DateTime endDate)
{
int firstQuarter = getQuarter(startDate);
int secondQuarter = getQuarter(endDate);
return 1 + Math.Abs(firstQuarter - secondQuarter);
}
private static int getQuarter(DateTime date)
{
return (date.Year * 4) + ((date.Month - 1) / 3);
}
public static int GetTotalYear(DateTime startDate, DateTime endDate)
{
int years = endDate.Year - startDate.Year;
if (startDate.Month == endDate.Month &&// if the start month and the end month are the same
endDate.Day < startDate.Day)// BUT the end day is less than the start day
{
years--;
}
else if (endDate.Month < startDate.Month)// if the end month is less than the start month
{
years--;
}
return Math.Abs(years);
}
}
}
EntityMapper:
public Mandate FromMandateCreateDtoToMandate(MandateVM mandateCreateVM)
{
if (mandateCreateVM == null)
{
return null;
}
Mandate mandate = new Mandate()
{
StartDate = mandateCreateVM.StartDate,
EndDate = mandateCreateVM.EndDate,
DueDate = mandateCreateVM.DueDate,
PaymentFrequency = mandateCreateVM.PaymentFrequency, //1=Monthly, 2=Quarterly, 3=Yearly
Amount = mandateCreateVM.Amount,
};
int numberOfTimes;
switch (mandateCreateVM.PaymentFrequency)
{
case 1:
return numberOfTimes = ConstantHelper.GetTotalMonth(mandate.StartDate, mandate.EndDate);
break;
case 2:
return numberOfTimes = ConstantHelper.GetTotalQuarter(mandate.StartDate, mandate.EndDate);
break;
default:
return numberOfTimes = ConstantHelper.GetTotalYear(mandate.StartDate, mandate.EndDate);
break;
}
mandate.PaymentCount = numberOfTimes;
return mandate;
}
PaymentFrequency determines number of times (numberOfTimes) payment will be made.
1 = Monthly
2 = Quarterly
3 = Yearly
I expected it to return numberOfTimes as int, but I got this error:
Error CS0029 Cannot implicitly convert type 'int' to 'Core.Models.Mandate'
It highlights:
return numberOfTimes = ConstantHelper.GetTotalMonth(mandate.StartDate, mandate.EndDate);
return numberOfTimes = ConstantHelper.GetTotalQuarter(mandate.StartDate, mandate.EndDate);
return numberOfTimes = ConstantHelper.GetTotalYear(mandate.StartDate, mandate.EndDate);
How do I get this resolved?
Thanks
Just delete the return in every cases of your switch case in FromMandateCreateDtoToMandate().
Those return will try to exit the function and return numberOfTimes (int) instead of, I presume, as you wanted only exit the switch case
I may not being using the correct term "nested", but you can see the 2 classes I have below. IEnumerable<OperationTask> is in the IEnumerable<AxApp>.
I hope I can explain this correctly:
I have a method that is reading values from a txt file into a string[]
string[] appNames = _appNamesRepository.GetAppNameListFromInputFile(fileName);
Then I create an IEnumerable<AxApp> collection with a method that reads a SQL table and returns the AxApp properties for each app value in the txt file.
IEnumerable<AxApp> allAxApps = _axAppRepository.GetAllAxAppsInList(appNames);
I need to filter the IEnumerable<AxApp> collection based on specific criteria from values in the IEnumerable<OperationTask>. I can get a basic lambda search to work, but I can't return the correct result if I have more than a couple values I'm basing this on.
For example the below will only return an IEnumerable<AxApp> if the appid, operationType, and operationStatus.Incomplete are NOT in IEnumerable<OperationTasks>.
var test = allAxApps.Where(app =>
!app.operationTasks
.Any(task => task.appId == app.appid &&
task.operationType == operationType &&
task.operationStatus != Status.Incomplete));
HOWEVER, I need to go a step further, if the operationType == "Differential", I can only return the AxApp IF IN IEnmerable<OperationTask> there is a collection where type = "NewConversion", status = "Complete", but NO type = "Finish", but can include types = "Differential"
public class AxApp
{
public AxApp()
{
}
public AxApp(int id, string appname, string dlname)
{
this.appname = appname;
appid = id;
this.dlname = dlname;
}
public string appname { get; set; }
public int appid { get; set; }
public string dlname { get; set; }
public string dtname { get; set; }
public int flags { get; set; }
public IEnumerable<AxDlsd> dlsdRecords { get; set; }
public IEnumerable<AxDl> dlRecords { get; set; }
public IEnumerable<OperationTask> operationTasks { get; set; }
public DateTime startMerge { get; set; }
public DateTime endMerge { get; set; }
}
public class OperationTask
{
public int operationId { get; set; }
public int appId { get; set; }
public OperationType operationType { get; set; }
public Status operationStatus { get; set; }
public DateTime startTime { get; set; }
public DateTime endTime { get; set; }
}
Method that returns the AppData from any value in the string[]
public IEnumerable<AxApp> GetAllAxAppsInList(string[] appNamesInput)
{
string query = #"SELECT appid, appname, dlname, dtname, flags FROM dbo.ae_apps WHERE appname = #_appname";
string opQuery = #"SELECT operationId, appId, operationType, operationStatus, startTime, endTime FROM dbo.RDS_ConversionOperationsHistory WHERE appid = #_appId";
using (var connection = _dbConnectionFactory.GetAxDbConnection())
{
foreach (string appname in appNamesInput)
{
AxApp result = connection.QuerySingle<AxApp>(query, new { _appname = appname });
result.operationTasks = connection.Query<OperationTask>(opQuery, new { _appId = result.appid });
yield return result;
}
}
}
IEnumerable for AxApp/OperationTask
[0] = {RDS.Conversion.UtilityLibrary.Models.AxApp}
[0] {RDS.Conversion.UtilityLibrary.Models.AxApp} RDS.Conversion.UtilityLibrary.Models.AxApp
appid 1 int
appname "PLIC_CENT_1" string
dlRecords null System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.AxDl
dlname "ae_dlsd1_SIM" string
dlsdRecords null System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.AxDlsd>
dtname "ae_dt1" string
endMerge {1/1/0001 12:00:00 AM} System.DateTime
flags 16384 int
operationTasks Count = 3 System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.OperationTask> {System.Collections.Generic.List<RDS.Conversion.UtilityLibrary.Models.OperationTask>}
startMerge {1/1/0001 12:00:00 AM} System.DateTime
operationTasks Count = 3 System.Collections.Generic.IEnumerable<RDS.Conversion.UtilityLibrary.Models.OperationTask> {System.Collections.Generic.List<RDS.Conversion.UtilityLibrary.Models.OperationTask>}
[0] {RDS.Conversion.UtilityLibrary.Models.OperationTask} RDS.Conversion.UtilityLibrary.Models.OperationTask
appId 1 int
endTime {1/1/0001 12:00:00 AM} System.DateTime
operationId 18 int
operationStatus Complete RDS.Conversion.UtilityLibrary.Models.Status
operationType NewConversion RDS.Conversion.UtilityLibrary.Models.OperationType
startTime {9/28/2018 12:53:51 PM} System.DateTime
I'm not sure if this is what you're looking for but, it may get you in the right direction.
test = allAxApps.Where(app =>
{
var tasks = app.operationTasks.ToList();
var differentialCondition = false;
if (operationType == OperationType.Differential)
{
var hasCompletedNewConversion = tasks.Any(task =>
task.operationType == OperationType.NewConversion &&
task.operationStatus == Status.Complete);
var hasFinish = tasks.Any(task => task.operationType == OperationType.Finish);
differentialCondition = hasCompletedNewConversion && !hasFinish;
}
var hasIncomplete = tasks.Any(task =>
task.appId == app.appid &&
task.operationType == operationType &&
task.operationStatus == Status.Incomplete);
return differentialCondition && !hasIncomplete;
});
I have a XML like this:
<PrayerTime
Day ="1"
Month="5"
Fajr="07:00"
Sunrise="09:00"
Zuhr="14:00"
/>
A class like this:
public class PrayerTime
{
public string Fajr { get; set; }
public string Sunrise { get; set; }
public string Zuhr { get; set; }
}
And something to get the value like this:
XDocument loadedCustomData = XDocument.Load("WimPrayerTime.xml");
var filteredData = from c in loadedCustomData.Descendants("PrayerTime")
where c.Attribute("Day").Value == myDay.Day.ToString()
&& c.Attribute("Moth").Value == myDay.Month.ToString()
select new PrayerTime()
{
Fajr = c.Attribute("Fajr").Value,
Sunrise = c.Attribute("Sunrise").Value,
};
myTextBox.Text = filteredData.First().Fajr;
How can i based by current time of day say that if time is between the value of Fajr and the Value of Sunrise, then myTextBox should show the value of Fajr.
If value of current time is between sunrise and Zuhr, show Zuhr?
How can i get it to show the attribute name in myTextBox2?
For example, myTextBox shows value "07:00", and myTextBox2 shows "Fajr"?
First modify the class as per #abatischcev
public class PrayerTime
{
public TimeSpan Fajr { get; set; }
public TimeSpan Sunrise { get; set; }
public TimeSpan Zuhr { get; set; }
}
Then modify the linq query select part as:
select new PrayerTime()
{
Fajr = TimeSpan.Parse(c.Attribute("Fajr").Value),
Sunrise = TimeSpan.Parse(c.Attribute("Sunrise").Value),
Zuhr = TimeSpan.Parse(c.Attribute("Zuhr").Value)
};
then your check should be:
var obj = filteredData.First();
TimeSpan currentTime = myDay.TimeOfDay;
string result = String.Empty;
if (currentTime >= obj.Fajr && currentTime < obj.Sunrise)
{
result = "Fajar";
}
else if (currentTime >= obj.Sunrise && currentTime < obj.Zuhr)
{
result = "Zuhar";
}
textbox1.Text = result;
(By the way, Zuhr time should be between Zuhr and Asar :))
First, keep not string but TimeSpan object:
public TimeSpan Fajr { get; set; }
public TimeSpan Sunrise { get; set; }
To do this parse XML into DateTime:
TimeSpan ts = TimeSpan.Parse(c.Attribute("attr"));
So:
TimeSpan now = DateTime.Now.TimeOfDay; // time part only
var data = filteredData.First();
string result = null;
if (data.Fajr <= now && now < data.Sunrise); // notice operators greed
result = data.Fajr;
else if (data.Sunrise <= now && now <= data.Zuhr)
result = data.Zuhr;
myTextBox.Text = result;
The problem here is your code is "stringly typed". I would be better to use type that is design for time e.g. DateTime, but to quick fix it:
// don't you need a third one here?
select new PrayerTime()
{
Fajr = c.Attribute("Fajr").Value,
Sunrise = c.Attribute("Sunrise").Value,
};
Tu get current hour:
int currentHour = DateTime.Now.Hour;
Then is just simple comparison of two integers.
var data = filteredData.First();
int fajrHour = int.Parse(data.Fajr.Substring(0, 2), CultureInfo.InvariantCulture);
int sunriseHour = int.Parse(data.Sunrise.Substring(0, 2), CultureInfo.InvariantCulture);
int zuhrHour = int.Parse(data.Zuhr.Substring(0, 2), CultureInfo.InvariantCulture);
if(fajrHour <= currenHour && currenHour < sunriseHour)
{
myTextBox.Text = data.Fajr; // or to show value fajrHour.ToString()
}
if(sunriseHour <= currenHour && currenHour < zuhrHour)
{
myTextBox.Text = data.Zuhr; // zuhrHour.ToString()
}
// don't you need a third one here?
I'm using the great .NET library AutoPoco for creating test and Seed Data.
In my model I have 2 date properties, StartDate and EndDate.
I want the EndDate to be 3 hours after the start Date.
I've created a custom Data source for autopoco below that returns a random Datetime between a min and max date
class DefaultRandomDateSource : DatasourceBase<DateTime>
{
private DateTime _MaxDate { get; set; }
private DateTime _MinDate { get; set; }
private Random _random { get; set; }
public DefaultRandomDateSource(DateTime MaxDate, DateTime MinDate)
{
_MaxDate = MaxDate;
_MinDate = MinDate;
}
public override DateTime Next(IGenerationSession session)
{
var tspan = _MaxDate - _MinDate;
var rndSpan = new TimeSpan(0, _random.Next(0, (int) tspan.TotalMinutes), 0);
return _MinDate + rndSpan;
}
}
But in AutoPoco's configuration how can i get my EndDate to be say, 3 hours after the autogenerated start Date?
Here's the autopoco config
IGenerationSessionFactory factory = AutoPocoContainer.Configure(x =>
{
x.Conventions(c => { c.UseDefaultConventions(); });
x.AddFromAssemblyContainingType<Meeting>();
x.Include<Meeting>()
.Setup((c => c.CreatedBy)).Use<FirstNameSource>()
.Setup(c => c.StartDate).Use<DefaultRandomDateSource>(DateTime.Parse("21/05/2011"), DateTime.Parse("21/05/2012"));
});
If I am correctly understanding the problem you need: to set EndDate from StartDate. I had to create a new DataSource and get current item which we are constructing and read value from it. I haven't thoroughly checked but it might fail if StartDate is set after EndDate (though I think the properties are set in the order they are setup, read source code for AutoPoco). Also I am using latest version from CodePlex as of today (20 Feb 2012).
public class MeetingsGenerator
{
public static IList<Meeting> CreateMeeting(int count)
{
var factory = AutoPocoContainer.Configure(x =>
{
x.Conventions(c => { c.UseDefaultConventions(); });
x.Include<Meeting>()
.Setup((c => c.CreatedBy)).Use<FirstNameSource>()
.Setup(c => c.StartDate).Use<DefaultRandomDateSource>
(DateTime.Parse("21/May/2012"),
DateTime.Parse("21/May/2011"))
.Setup(c => c.EndDate).Use<MeetingEndDateSource>(0, 8);
});
return factory.CreateSession().List<Meeting>(count).Get();
}
}
public class Meeting
{
public string CreatedBy { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
public class MeetingEndDateSource : DatasourceBase<DateTime>
{
private int mMin;
private int mMax;
private Random mRandom = new Random(1337);
public MeetingEndDateSource(int min, int max)
{
mMin = min;
mMax = max;
}
public override DateTime Next(IGenerationContext context)
{
var node = (TypeGenerationContextNode)((context.Node).Parent);
var item = node.Target) as Meeting;
if (item == null)
return DateTime.Now;
return item.StartDate.AddHours(mRandom.Next(mMin, mMax + 1));
}
}
class DefaultRandomDateSource : DatasourceBase<DateTime>
{
private DateTime _MaxDate { get; set; }
private DateTime _MinDate { get; set; }
private Random _random = new Random(1337);
public DefaultRandomDateSource(DateTime MaxDate, DateTime MinDate)
{
_MaxDate = MaxDate;
_MinDate = MinDate;
}
public override DateTime Next(IGenerationContext context)
{
var tspan = _MaxDate - _MinDate;
var rndSpan = new TimeSpan(0
, _random.Next(0, (int)tspan.TotalMinutes)
, 0);
return _MinDate + rndSpan;
}
}
I have a class Similar to this
public class Model
{
public TimeSpan Time1 {get; set;}
public TimeSpan Time2 { get; set; }
public TimeSpan Time3 { get; set; }
public TimeSpan Time4 { get; set; }
}
Now Let's Imagine I have to populate the times during runtime and then Figure out the time remaining between Time 1 and Time 2, then when that passes Find the time remaining between Time2 and Time3 and so on. However, I need to take into account what the time is right now.
For Example:
Now it is 1:00 PM
Time1=5:00 AM
Time 2 = 12:00 PM
Time 3= 4:00 PM
Time 4 = 6:00 PM
So since the time is 1:00PM, I need to find the difference between Time 2 and Time 3
Now is there a smarter way other than reflection to determine this? Should i add something in my class
If you need to keep the existing structure of your class, you could add a method to enumerate through the times:
public class Model
{
public TimeSpan Time1 {get; set;}
public TimeSpan Time2 { get; set; }
public TimeSpan Time3 { get; set; }
public TimeSpan Time4 { get; set; }
public IEnumerable<TimeSpan> GetTimes()
{
yield return Time1;
yield return Time2;
yield return Time3;
yield return Time4;
}
}
And use it like this:
foreach (TimeSpan time in model.GetTimes())
{
// use the TimeSpan
}
Why would you not use an array or list?
public class Model
{
public List<DateTime> Dates { get; set; }
}
If I'm understanding your question correctly, why not have a Dictionary<TimeSpan, string> where the key is actual TimeSpan, and the value is the name, e.g. "Time1"? This way, you can sort the keys, find the pair that you need, and then get at their names.
You could add a property or method that would return the times as a list for easier processing. Then your external code could access the times as either a list or as individual properties. You still have to explicitly access each property, but at least it's from within the same class, so you're not coupling your external code to the data structure as tightly.
This is untested and needs some optimization, but just as a thought example, use an array and iterate through it.
public class Model
{
private TimeSpan[] _timeSpans = new TimeSpan[4] { new TimeSpan(), new TimeSpan(), new TimeSpan(), new TimeSpan() };
public TimeSpan Time1
{
get { return _timeSpans[0]; }
set { _timeSpans[0] = value; }
}
public TimeSpan Time2
{
get { return _timeSpans[1]; }
set { _timeSpans[1] = value; }
}
public TimeSpan Time3
{
get { return _timeSpans[2]; }
set { _timeSpans[2] = value; }
}
public TimeSpan Time4
{
get { return _timeSpans[3]; }
set { _timeSpans[3] = value; }
}
// DateTime.TimeOfDay holds the time portion of a time
public TimeSpan GetDifference(TimeSpan currentTime)
{
int start = -1;
for(int i = 0; i<_timeSpans.Length;i++)
{
if(_timeSpans[i] >= currentTime)
{
start = i;
break;
}
}
if(start == -1) throw new ArgumentException("handle the case where currentTime is smaller than all of them");
int end = (start + 1 < _timeSpans.Length) ? start + 1 : 0;
return _timeSpans[end] - _timeSpans[start];
}
Constructing an array provides for a simple linq statement to calculate the time span:
public class Model
{
public TimeSpan Time1 { get; set; }
public TimeSpan Time2 { get; set; }
public TimeSpan Time3 { get; set; }
public TimeSpan Time4 { get; set; }
public TimeSpan GetSpan(TimeSpan time)
{
var times = new[] { Time1, Time2, Time3, Time4 };
return Enumerable.Range(1, times.Length - 1)
.Select(i => new[] { times[i - 1], times[i] })
.Where(t => t[0] <= time && time < t[1])
.Select(t => t[1] - t[0])
.FirstOrDefault();
}
}